- 참조: 자바 ORM 표준 JPA 프로그래밍
- QueryDSL 시작
여태까지 살펴본 Criteria 는 문자열로 작성한 JPQL 과는 다르게 문법 오류를 컴파일에서 잡을 수 있었지만 코드를 살펴보면 직관적이지 않은 부분이 있었다. QueryDSL 은 HQL 을 코드로 작성하기 위한 오픈소스 프로젝트 였지만 현재는 JPA, JDO, JDBC 등 여러 디비 제품군을 지원하고 있다.
- 설정
JPA 카테고리 JPA - 객체지향 쿼리 언어 - 개요 글에서 QueryDSL 설정법을 살펴본적이 있지만 다시 한번 살펴보도록 하자.
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
............
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
pom.xml 에 위와 같이 dependency 와 plugin 을 설정해주어야 한다. dependency 의 querydsl-jpa 는 QueryDSL 을 사용하기 위한 기본적인 라이브러리이며 querydsl-apt 는 Criteria 의 Meta model 과 같이 엔티티를 기반으로 Q-type 이라는 클래스를 생성하기 위해 필요한 라이브러리이다.
그 후 콘솔에 mvn compile 을 입력해주면 Q-type 이 생성된다.
- 기본 사용
예제를 한번 살펴보자.
Member member1 = new Member();
member1.setName("Name#1");
member1.setAge(10);
member1.setAddress(
new Address("City#1", "Street#1", "Zipcode#1"));
em.persist(member1);
Member member2 = new Member();
member2.setName("Name#2");
member2.setAge(13);
member2.setAddress(
new Address("City#1", "Street#2", "Zipcode#2"));
em.persist(member2);
Member member3 = new Member();
member3.setName("Name#3");
member3.setAge(32);
member3.setAddress(
new Address("City#2", "Street#3", "Zipcode#3"));
em.persist(member3);
Member member4 = new Member();
member4.setName("Name#4");
member4.setAge(22);
member4.setAddress(
new Address("City#2", "Street#4", "Zipcode#4"));
em.persist(member4);
.................
JPAQueryFactory query = new JPAQueryFactory(em);
QMember qMember = new QMember("m");
List<Member> members = query.select(qMember)
.from(qMember)
.where(qMember.age.gt(20))
.orderBy(qMember.age.desc())
.fetch();
members.forEach(member -> {
System.out.println("Member age: " + member.getAge());
});
위의 코드는 Member 4 명의 엔티티를 영속시킨 후 나이 20 초과조건을 조회한 다음 내림 차순으로 정렬한 예제이다.
QueryDSL 을 사용하려면 JPAQueryFactory 에 엔티티매니저를 인자로 넘겨준 후 사용하면 된다. 그 후 query 를 이용해서 JPQL 을 빌딩하는 코드를 잘 살펴보면 느끼는 점이 있을 것이다. Criteria 와는 다르게 상당히 직관적임을 알 수 있다.
Hibernate:
/* select
m
from
Member m
where
m.age > ?1
order by
m.age desc */ select
member0_.member_id as member_i1_6_,
member0_.insert_datetime as insert_d2_6_,
member0_.update_datetime as update_d3_6_,
member0_.city as city4_6_,
member0_.street as street5_6_,
member0_.zipcode as zipcode6_6_,
member0_.age as age7_6_,
member0_.name as name8_6_
from
member member0_
where
member0_.age>?
order by
member0_.age desc
Member age: 32
Member age: 22
조회된 결과에서 주석에 나온 JPQL 을 보면 거의 순서도 일치하며 query 를 사용하기 위해 예약어와 표현식을 위하 CriteriaQuery 와 CriteriaBuilder 를 따로 사용하지 않고, query 에서 예약어를 표현하며 Q-type 에서 표현을 사용한다.
- Default Q-Type 생성
기본 예제에서는 QMember 생성시 "m" 문자열 인자를 넘겨주어 별칭을 별도로 지정하였다. 이는 Join 을 사용할 시 별칭을 다르게 사용해야 할 경우가 있기 때문이다. 만약 그렇지 않다면 기본으로 제공하는 Q-Type 을 이용할 수 있다.
JPAQueryFactory query = new JPAQueryFactory(em);
QMember qMember = QMember.member;
List<Member> members = query.select(qMember)
.from(qMember)
.where(qMember.age.gt(20))
.orderBy(qMember.age.desc())
.fetch();
members.forEach(member -> {
System.out.println("Member age: " + member.getAge());
});
QMember.member 를 사용하면 기본제공 Q-Type 을 생성한다. 위의 코드를 실행하면 member1 이라는 별칭으로 JPQL 이 생성되는것을 알 수 있는데 이는 Q-Type 소스를 보면 왜 그런지를 알 수 있다.
/**
* QMember is a Querydsl query type for Member
*/
@Generated("com.querydsl.codegen.EntitySerializer")
public class QMember extends EntityPathBase<Member> {
private static final long serialVersionUID = -925484204L;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QMember member = new QMember("member1");
..................
'Framework and Tool > JPA' 카테고리의 다른 글
JPA - 객체지향 쿼리 언어 - QueryDSL Join, 서브쿼리 (0) | 2021.08.18 |
---|---|
JPA - 객체지향 쿼리 언어 - QueryDSL 검색조건, 페이징, 그룹 (0) | 2021.08.16 |
JPA - 객체지향 쿼리 언어 - Criteria 메타 모델 API (0) | 2021.08.13 |
JPA - 객체지향 쿼리 언어 - Criteria 파라미터, 네이티브 함수 (0) | 2021.08.12 |
JPA - 객체지향 쿼리 언어 - Criteria 서브 쿼리 (0) | 2021.08.11 |
댓글