JPQL
- JPQL ? 엔티티 객체를 조회하는 개체지향 쿼리
- SQL을 추상화했기때문에 특정 디비에 의존하지 않는다.
SELECT
- TypeQuery ? 작성한 JPQL을 실행하기 위한 쿼리 객체로 반환 타입을 명확하게 지정할 수 있는 경우에 사용
- 단순 Query객체 사용할 경우 Object 타입으로 리턴되기 때문에 타입변환이 필요함.
- getResultList(), getSingleResult()
- 파라미터 바인딩
- 이름 기준
- Select m From Member m where m.username = :username
- .setParameter(”username”, userNameParam)
- 포지션 기준
- Select m From Member m where m.username = ?1
- .setParameter(1, userNameParam)
- 이름 기준을 선택하는 것이 더 명확함.
Projection
- SELECT절에 조회할 대상을 지정하는 것
- 여러값 조회시 TypeQuery를 사용할 수 없으므로 매변 변환작업을 해줘야하는데 new를 쓰면 간단하다
- em.createQuery(”SELECT new jpabook.jqpl.UserDTO(m.username, m.age) FROM Member m);
- Paging API
- .setFirstResult → offset
- .setMaxResult → 조회할 건수
JOIN
- fetchJoin ?
- 엔티티 객체 그래프를 한 번에 조회하는 방법
- select m from Member m join fetch m.team
- SELECT M., T. FROM MEMBER T INNER JOIN TEAM T ON M.TEAM_ID = T.ID
- 단순 조인과 비교할때 성능상의 이점이 있음
- 단순 조인시에는 조인만 될 뿐, 의도한대로 연관관계에 있는 엔티티의 값을 리턴해주지는 않는다.
- 따라서 만약 List롤 멤버엔티티를 조회했다면 lazy loading일때 멤버의 연관관계가 있는 팀의 이름을 조회할 때마다 쿼리가 날아감
- 즉 10000건의 목록조회 쿼리 한건을 의도했는데 10000건의 팀에 대한 조회쿼리가 발생하게 됨 (N+1)
- 조회 대상 엔티티를 조회할 때 페치 조인을 사용하면 연관된 엔티티는 프록시가 아닌 실제 엔티티이다.
- fetchjoin의 특징과 한계
- 특징
- SQL 한 번으로 연관된 엔티티들을 함께 조회할 수 있어서 성능 최적화가 가능하다
- 글로벌 로딩 전략은 지연로딩 사용하고 최적화가 필요하면 페치 조인을 사용하는 것이 효과적
- 페치 조인을 사용하면 기본적으로 연관된 엔티티는 준영속상태(영속성컨텍스트에 의해 관리되지 않는 상태)임에도 객체 그래프 탐색이 가능함.
- 페치 조인해서 가져온 객체를 수정하면 그럼 더티체크가 안되고 수정이 안된다는거?
- 한계
- 별칭을 줄 수 없음
- 둘 이상의 컬렉션을 페치할 수 없음
- 페이징 api 쓸 수 없음
NamedQuery
- 정적 쿼리로 로딩 시점에 JPQL 문법 체크하여 미리 파싱해 놓음
- 따라서 컴파일 시점에 문법 오류를 잡을 수 있다는 장점이 있음