-
13. JPA에서 사용하는 다양한 쿼리 방법웹개발/Hibernate(JPA) 2020. 5. 7. 14:51
안녕하세요 현우입니다. 이번 포스팅은 [ JPA에서 사용되는 다양한 쿼리 사용방법 ] 입니다. 동적 쿼리를 사용하기 위해 사용되는 JPA에서 지원하는 다양한 쿼리의 사용방법을 간단하게 소개 해보겠습니다.
참고서 http://acornpub.co.kr/book/jpa-programmig
회원의 이름을 조회하는 쿼리문이 필요할 경우 엔티티 매니저 팩토리를 생성하고 팩토리에서 지원하는 find 함수를 사용하여 아주 간단하게 회원의 이름을 조회할 수 있습니다.
알고 있는 바와 같이 find 함수로 위와 같이 쿼리문을 생성하고 DB에 트랜잭션을 날린 후 원하는 결과 를 얻을 수 있습니다. 만약 쿼리문에 조건절이 생기면 어떻게 검색해야 할까요?
EX) '나이가 18살 이상인 회원을 모두 검색하세요'
find() 함수는 id값 만을 받아 조회하므로 우리가 원하는 결과를 얻을 수 없습니다. JPA를 사용하면 테이블과 매핑만 되며 Entity객체를 중심으로 개발합니다.
즉 검색을 할때도 테이블이 아닌 엔티티 객체를 대상으로 검색을 하는데 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색조건이 포함된 SQL쿼리 문이 필요합니다.
1. JPQL
JPA는 SQL을 추상화한 JPQL이라는 객체지향 쿼리언어를 제공합니다.
JPQL은 안심표준이라하여 SQL과 문법이 유사한 select, from, where, group by, having, join과 같은 모든 쿼리를 지원하며 가장 큰 차이점은 JPQL은 엔티티 객체를 대상으로 쿼리를 하고, SQL은 데이터베이스 테이블을 대상으로 쿼리를 한다는 것 입니다.
① 주석으로 JPQL문이 먼저 나간다음에 엔티티의 매핑정보를 읽습니다.
② 실제 DB에 SQL문이 날아갑니다.
SQl을 추상화해서 특정 데이터베이스에 의존하지 않는 모습을 보여주는 것이 JPQL의 장점입니다. 하지만 JPQL의 쿼리문은 단순 문자열이므로 동적쿼리를 만들기 위해서는 문자열을 가공(+,-)하여야 하므로 어려움이 많습니다.
2. Criteria 동적쿼리 만들기
Criteria는 문자가아닌 자바코드로 퀴리문을 짜기 때문에 문법 오류를 잡아낼 수 있으며 JPQL 보다 쉽게 동적쿼리를 작성 할 수 있습니다.
자바코드로 작성하면 컴파일타임 오류가 나기때문에 SQL문법 때문에 오류가나는 문제는 없지만, 너무 복잡하고 실용성이 없어서 잘 쓰지 않습니다. (SQL문과 너무 동떨어져있기 때문에 디버깅이 거의 불가능)
Criteria 대신에 QueryDSL 사용을 권장합니다.
3. QueryDsl 동적쿼리만들기
문자가아닌 자바코드로 JPQL을 작성이 가능합니다. JPQL에 대한 빌더역할을 하며 컴파일 시점에 문법 오류를 찾을 수 있으며 동적쿼리 작성이 편리하여 문법자체가 SQL문과 비슷하여 단순하고 익히기 쉽습니다.
(문법버그가 생기지 않습니다)
/** * QUERY DSL 은 컴파일에서 에러를 걸러낸다! */ // 실제 DB쿼리문과 굉장히 유사하다. public void hello(){ QMember m = QMember.member; List<Member> result = queryFactory .select(m) //member을 불러온다 .from(m) // m에서 .where(m.name.like("kim")) //name컬럼에 kim조건 .orderBy(m.id.desc()) // 아이디값 기준 내림차순 .fetch(); } @Overide public List<Order> findAllByQuerydsl(OrderSearch orderSearch){ return queryFactory .select(order) .from(order) .join(order.member, member) //조인쿼리 .where(statusEq(orderSearch), memberNameEq(orderSearch)) //동적쿼리 손쉽게 작성 .fetch(); } // 작업 코드 재사용 private BoleanExpression memberNameEq(orderSearch orderSearch){ return hasText(orderSearch.getMembername()) ? member.name.eq(orderSearch.getMemberName()) : null; } private BoleanExpression statusEq(orderSearch orderSearch){ return orderSearch.getOrderStatus() != null ? order.status.eq(orderSearch.getOrderStatus()) : nll; }
JPA가 제공하는 SQL을 직접 사용이 가능하며 JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능을 사용 할 수 있습니다.
ex) 오라클의 connectBy, 특정 DB만 사용하는 SQL hint
공식 사이트에 많은 튜토리얼이 있습니다.
'웹개발 > Hibernate(JPA)' 카테고리의 다른 글
12. 데이터 타입 분류 (0) 2020.05.01 11. 영속성 전이(CASCADE)와 고아 객체 (0) 2020.04.28 10. 즉시 로딩과 지연 로딩 (0) 2020.04.28 9. 프록시와 연관관계 (0) 2020.04.25 7. 고급매핑 (0) 2020.04.20