QueryDSL은 JPA를 사용하여 데이터베이스 쿼리를 작성하고 실행하기 위한 유용한 도구이다.
QueryDSL을 사용하면 Java 코드로 쿼리를 작성할 수 있어서, 컴파일 타임 오류확인 및 IDE의 자동완성 기능을 사용할 수 있다.
QueryDSL?:
- JPA Entity와 관련된 쿼리를 생성하기 위한 builder 라이브러리이다.
- SQL을 직접 작성하는 대신, Java 코드를 사용하여 query를 작성할 수 있다.
Entity와 Q타입:
- Entity의 메타 모델을 사용하여 query를 작성하기 때문에 Entity클래스에 대응하는 Q타입 클래스가 필요하다.
ex) Customer -> QCustomer
문법:
- QueryDSL은 Java코드로 작성되며, MethodChaining을 사용하여 query를 작성한다.
- (select, from, where, join, fetch) 등의 메서드를 사용하여 qeury를 구성한다.
특징:
- 컴파일 타입 검증 - Java 코드로 작성되기 때문에 컴파일 시 문법 오류를 확인 가능.
- 자동 완성 - IDE의 자동 완성이나 코드 어시스트를 받을 수 있음.
- 타입 안전성 - Entity 속성 이름이나 조건은 컴파일 시 검증되기 때문에 타입에 안전함.
Plugin&Dependency 추가
plugins {
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
dependencies {
implementation 'com.querydsl:querydsl-jpa:{버전}'
implementation 'com.querydsl:querydsl-apt:{버전}'
}
Example >
Entity 생성
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String firstname;
@Column
private String surname;
Person() {
}
public Person(String firstname, String surname) {
this.firstname = firstname;
this.surname = surname;
}
// standard getters and setters
}
JPAQueryFactory
- QueryDSL의 핵심 클래스로 JPAQuery를 생성하고 실행하는데 사용된다.
- JPAQueryFactory로부터 계속 JPAQuery객체를 생성하고 사용할 수 있기 때문에 한번만 객체를 생성하면 된다.
JPAQuery
- 개별적인 JPAQuery를 생성하고 실행하는데 사용된다.
- JPAQuery는 한 번 사용한 후에는 재사용할 수 없다.
Q타입과 JPAQuery 객체 생성
// Q Type
QPerson person = QPerson.person;
/* QPerson person = new QPerson("Erich", "Gamma"); */
// JPAQueryFactory
JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
// JPAQuery
/* JPAQuery query = new JPAQuery(entityManager); */
JPAQueryFactory 주요 메서드
selectFrom():
쿼리의 시작을 나타내며 모든 컬럼(*)을 반환하게 된다.
ex> selectFrom(user)
from():
쿼리의 시작을 나타내며 select() 메서드로 반환할 컬럼을 지정할 수 있다.
ex> select(user.name).from(user)
where():
필드값을 비교하는 등의 조건을 추가한다.
ex> where(user.name.eq("John"))
orderBy():
쿼리 결과를 정렬한다.
ex> orderBy(user.name.asc())
groupBy():
그룹화를 위해 사용하며, having()은 그룹화된 결과에 대한 조건을 추가한다.
ex> groupBy(user.name).having(user.age.avg.gt(30))
fetch():
쿼리를 실행하고 결과를 가져오는 역할을 한다. fetchFirst(): 첫 번째 결과
ex> selectFrom(user).fetch();
join():
Entity간의 내부조인 수행. (leftJoin, rightJoin)
on() 으로 조건을 지정할 수 있지만 자동으로 Entity간의 관계를 이용하여 매핑된다.
ex> innerJoin(user.address, address)
limit():
가져올 결과의 개수를 제한한다.
ex> limit(5)
offset():
시작 위치를 지정한다. (주로 페이징 처리에 사용) ex> offset(1)
transform():
결과를 특정 타입으로 변환할 때 사용된다.
ex> transform(Transformers.aliasToBean(UserDTO.class)
JPAQueryFactory로 데이터 조회
// JPAQueryFactory 생성
JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
// 여러 데이터 List로 조회
List<Person> persons = queryFactory
.selectFrom(person)
.where(person.firstName.eq("Kent"))
.fetch();
// 가장 큰 age 조회
NumberPath<Integer> maxAge = person.age.max();
int maxAgeResult = queryFactory
.select(maxAge)
.from(person)
.fetchOne();
// AND 조건
List<Person> andConditionResult = queryFactory
.selectFrom(person)
.where(person.firstName.eq("Kent")
.and(person.surname.eq("Beck")))
.fetch();
// OR 조건
List<Person> orConditionResult = queryFactory
.selectFrom(person)
.where(person.firstName.eq("Kent")
.or(person.surname.eq("Beck")))
.fetch();
// GroupBy 집계
Map<String, Integer> groupByResult = queryFactory
.select(person.firstName, person.age.max())
.from(person)
.groupBy(person.firstName)
.transform(GroupBy.groupBy(person.firstName).as(GroupBy.max(person.age)));
reference.
https://www.baeldung.com/querydsl-with-jpa-tutorial
'🍃SpringFramework > SpringDataJPA' 카테고리의 다른 글
[JPA] Native Query. 네이티브 쿼리 (0) | 2023.09.25 |
---|---|
[JPA] Entity와 Entity Manager & 영속성 컨텍스트 (0) | 2023.09.25 |
[JPA] JPQL (Java Persistence Query Language) (0) | 2023.09.25 |
[JPA] Query Method. 쿼리 메서드 (0) | 2023.09.25 |
[JPA] JPA Lock의 개념과 사용 (0) | 2023.09.11 |