쿼리 작성방법
- JPQL
- JpaRepsitory 인터페이스
- Specification
- QueryDSL
QueryDSL 이란?
JPQL 빌드
참고 사이트 : querydsl.com
JPQL 조회방식
- JPQL 호출하면 DB 우선 조회 (JPA 는 영속성컨텍스트 우선 조회)
- 조회한 값을 영속성 컨텍스트에 저장 시도
- 저장 시도할때 해당 데이터가 이미 존재하는경우, DB에서 조회한 신규 데이터는 버리고, 영속성 컨텍스트 데이터 리턴
QueryDSL 사용방법
QueryDSL 라이브러리가 제공하는 Q클래스 인스턴스로 QueryDSL 문법에 맞게 동적 쿼리 작성
1. QueryFactory 빈 생성
2. Q클래스 생성 : maven or gradle 빌드
3. 코드 작성
(예제) Member 테이블에서 이름이 "홍길동"인 항목 조회
QMember qMember = QMember.member;
List<Member> members = queryFactory.select(qMember)
.from(qMember)
.where(qMember.username.eq("홍길동"))
.fetch();
JPA 내에 QueryDSL 녹이기
기존에 사용하는 JPA 코드에 QueryDSL 적용하기
1. XXXRepositoryCustem 인터페이스 작성 및 구현 클래스 작성
- queryDSL 로 작성된 함수
2. 사용중인 JpaReository 에 XXXRepositoryCustom 인터페이스 구현
-
즉, MemberRepository 는 JpaRepository 도 상속받고, XXXRepositoryCustom 도 상속받아
JPA 와 QueryDSL 모두를 memberRepsitory 통해 사용가능
QueryDSL 성능개선
성능개선 내용
1. Entity 조회 대신 Dto 조회
(예제) Member 테이블에서 이름이 "홍길동"인 항목 조회
QMember qMember = QMember.member;
List<Member> members = queryFactory.select
(Projections.fields(MemberDto.class, memebr.username))
.from(qMember)
.where(qMember.username.eq("홍길동"))
.fetch();
2. 패티 조인과 페이징 동시사용시 Memeory Leak 이슈
- 현상 : 발생하는 db 쿼리에 limit 없이 쿼리 발생하나, 다음의 에러가 보이면서 페이징 결과는 정상리턴
- 에러 : firstResult/maxResults specified with collection fetch; applying in memory
- 원인 : 전체 조회를 해서 메모리에 올리고, 그중 페이징에 해당하는 결과만 리턴하여 결과 조회는 이상없어 보이나 잠재적인 메모리 Leak 문제를 가지고 있음
- 대책 : 확인중
로그팁
QueryDSL 은 JPQL 빌더이기 때문에 db 쿼리 말고도, JPQL 쿼리도 확인 필요함
hibernate.use_sql_comments=true