프로젝트 성능개선, 안티패턴 개선을 하면서 한 가지 의문이 들었다. 우선 현재 로직을 간단하게 설명하자면, @JwtLogin이 붙여져 있는 곳은 HandlerMethodArgumentResolver를 구현하여 헤더의 정보를 읽어 로그인한 멤버의 정보를 넘기는 방식이다. 코드의 흐름은 아래와 같다. Controller @PostMapping public ResponseEntity create(@JwtLogin final Member member, @RequestBody @Valid final BoardRequest boardRequest) { Board board = boardService.create(boardRequest, member); return ResponseEntity.status(HttpSt..
Spring Data JPA가 기본적으로 제공해 주는 CRUD 메서드 및 쿼리 메서드 기능을 사용하더라도, 원하는 조건의 데이터를 수집하기 위해서는 필연적으로 JPQL을 작성하게 된다. 간단한 로직을 작성하는데 큰 문제는 없으나, 복잡한 로직의 경우 개행이 포함된 쿼리 문자열이 상당히 길어진다. JPQL 문자열에 오타 혹은 문법적인 오류가 존재하는 경우, 정적 쿼리라면 애플리케이션 로딩 시점에 이를 발견할 수 있으나 그 외는 런타임 시점에서 에러가 발생한다. 이러한 문제를 어느 정도 해소하는데 기여하는 프레임워크가 QueryDSL이다. QueryDSL은 정적 타입을 이용해서 SQL 등의 쿼리를 생성해주는 프레임워크이다. QueryDSL의 장점 문자가 아닌 코드로 쿼리를 작성함으로써, 컴파일 시점에 문법 ..
페치 조인(fetch join) 페치 조인이란 SQL 조인의 종류가 아니며, JPQL에서 성능 최적화를 위해서 제공해주는 기능이다. 페치 조인은 엔티티를 조회할 때 연관된 엔티티나 컬렉션을 한 번의 SQL로 함께 조회하는 기능을 제공함으로써 N+1문제를 해결할 수 있게 도와준다. 일반 조인은 실행 시 연관된 엔티티를 함께 조회하지 않는다. 단지 데이터베이스 상에서 테이블간의 탐색을 위해 사용되는 것이다. 아래와 같은 코드가 있다고 하자. @Entity @Data public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private int age; ..
JPQL(Java Persistence Query Language) JPQL은 SQL을 추상화하여 특정 데이터베이스 SQL에 의존적이지 않은 객체지향 쿼리 언어이다. 테이블을 대상으로 쿼리를 하는 것이 아닌 객체(엔티티)를 대상으로 쿼리를 하기에 객체지향 쿼리 언어라고 불린다. JPQL은 결국 SQL로 변환되어 데이터베이스에 전달된다. ex) select m from Member as m where m.age > 20 엔티티와 속성은 대소문자를 구분한다. (Member, age) JPQL 키워드는 대소문자를 구분하지 않는다. (SELECT, select 모두 가능) 테이블이 아닌 엔티티의 이름을 사용한다. (Member) 별칭은 필수다. (m) (as는 생략 가능) EXISTS, IN, AND, OR, ..
JPA의 데이터 타입 분류 엔티티 타입 @Entity로 정의하는 객체 데이터가 변해도 식별자로 지속해서 추적 가능 ex) 멤버 엔티티의 나이, 번호 값을 변경해도 식별자로 인식 가능 값 타입 int, Integer, String처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체 식별자가 없고 값만 있으므로 변경시 추적 불가 ex) 숫자 10을 30으로 변경하면 완전히 다른 값으로 대체 갑 타입 분류 기본값 타입 - 자바 기본 타입, 래퍼 클래스, String 임베디드 타입 컬렉션 값 타입 기본값 타입 생명주기를 엔티티의 의존한다. 값 타입은 공유하면 안된다. 기본 타입은 항상 값을 복사한다. 값을 공유 X 임베디드 타입(복합 값 타입) 새로운 값 타입을 직접 정의할 수 있음 JPA는 임베디드 타입이라 ..
프록시란? Proxy, 영어로 '대리인'이라는 뜻이 있다. 말 그대로 엔티티에 대한 대리인의 역할을 한다. 그 말대로, 프록시는 원본 객체가 아닌 원본에 대한 복제품을 가져오는 것이다. 다음과 같은 테이블이 있다고 하자. 만약 회원을 조회할 때, 팀도 함께 조회될까? 멤버 엔티티는 아래와 같은 값을 가지며, setter, getter를 포함한다고 하자. @Entity public class Member{ @Id @GeneratedValue @Column(name = "member_id") private Long id; @Column(name = "username") private String name; @ManyToOne private Team team; } 팀 엔티티는 아래와 같은 값을 가지며, set..
엔티티 매핑 객체와 테이블 매핑 @Entity, @Table 필드와 컬럼 매핑 @Column 기본 키 매핑 @Id 연관관계 매핑 @ManyToOne, @JoinColumn @Entity Entity가 붙은 클래스는 JPA가 관리, 엔티티라 함 JPA를 사용해서 테이블과 매필할 클래스는 @Entity 필수 기본 생성자 필수 final 클래스, enum, interface, inner클래스 사용 x 데이터베이스 스키마 자동 생성 DDL을 애플리케이션 실행 시점에 자동 생성 테이블중심 -> 객체 중심 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성 생성된 DDL은 개발 장비에서만 사용 생성된 DDL은 운영서버에서는 사용 X, 다듬어서 사용 기본 키 매핑 방법 직접 할당: @Id만 사용 자동..
영속성 콘텍스트 "엔티티를 영구 저장하는 환경"이라는 뜻 영속성 콘텍스트는 논리적인 개념이다. 눈에 보이지 않는다. 엔티티 매니저를 통해서 영속성 콘텍스트에 접근한다. 엔티티의 생명주기 비영속(new/transient) 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태 영속(managed) 영속성 컨텍스트에 관리 되는 상태 준영속(detached) 영속성 컨텍스트에 저장되었다가 분리된 상태 삭제(removed) 삭제된 상태 //객체를 생성한 상태(비영속) Member member = new Member(); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); //객체를 저장한 상태(영속) em.persist(member); ..
JPA란? Java persistence API이다 persistence : Persistence(영속성) : 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미, 영속성은 파일 시스템, 관계형 데이터베이스 혹은 객체 데이터베이스 등을 활용하여 구현 자바에 있는 데이터를 영구히 기록할 수 있는 환경(스토리지 내 DBMS)에 영구히 저장할 수 있도록 하는 환경을 제공하는 API라고 할 수 있음 API (Application Programming Interface) : 프로그램 사이 데이터 통신 규칙(상하관계가 존재) ↔ Protocol Protocol은 서로 동일시하여 규칙을 서로 합의하에 정함 JPA는 ORM 기술이다. ORM(Object Relation Mapping) :..