개인적으로 오픈소스 프로젝트 중에 가장 좋아하시는 프로젝트
jpql을 자바 코드로 작성할 수 있도록 해준다. 기존에 criteria 라는 프로젝트가 있지만 사실상 매우 복잡하다. 실무에서 사용하기 힘들다.
JPA에서 잘 안 풀리는 문제가 동적 쿼리에 대한 문제가 있었다. (검색 조건)
Querydsl은 아예 다른 아이디어로 이 문제를 해결했다.
직접 한번 해보자. OrderSearch 쿼리를 해보자.
먼저 Q라는 파일을 생성해야 한다. 약간의 단점
buildscript {
dependencies {
classpath('gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10')
}
}
plugins {
id 'org.springframework.boot' version '2.1.9.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
apply plugin: 'com.ewerk.gradle.plugins.querydsl'
group = 'jpabook'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.querydsl:querydsl-jpa'
implementation 'com.querydsl:querydsl-apt'
}
def querydslDir = 'src/main/generated'
querydsl {
library = 'com.querydsl:querydsl-apt'
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', querydslDir]
}
}
}
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
task → other → compileQuerydsl 실행
import static jpabook.jpashop.domain.QMember.*;
import static jpabook.jpashop.domain.QOrder.*;
@Repository
public class OrderRepository {
private final EntityManager em;
private final JPAQueryFactory query;
public OrderRepository(EntityManager em) {
this.em = em;
this.query = new JPAQueryFactory(em);
}
public void save(Order order) {
em.persist(order);
}
public Order findOne(Long id) {
return em.find(Order.class, id);
}
public List<Order> findAll(OrderSearch orderSearch) {
return query
.select(order)
.from(order)
.join(order.member, member)
.where(statusEq(orderSearch.getOrderStatus()), nameLike(orderSearch.getMemberName()))
.limit(1000)
.fetch();
}
private BooleanExpression statusEq(OrderStatus statusCond) {
if (statusCond == null) {
return null;
}
return order.status.eq(statusCond);
}
private BooleanExpression nameLike(String nameCond) {
if (!StringUtils.hasText(nameCond)) {
return null;
}
return member.name.like(nameCond);
}
// ...