기존의 코드랩 프로젝트에서 QueryDsl을 써보았기 때문에 은행 입출금 프로젝트에서 JPQL 동적쿼리로 작성한 걸 Querydsl 설정을 추가하고 적용한 내용을 블로그 포스팅 해보려고 합니다.
buildscript {
ext {
queryDslVersion = "5.0.0"
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.13'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}
group = 'shop.mtcoding'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '11'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
querydsl.extendsFrom compileClasspath
}
repositories {
mavenCentral()
}
dependencies {
// https://mvnrepository.com/artifact/com.auth0/java-jwt
implementation group: 'com.auth0', name: 'java-jwt', version: '4.2.1'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
//Spring security
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
// QueryDSL
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
}
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main.java.srcDir querydslDir
}
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
}
tasks.named('test') {
useJUnitPlatform()
}
jar{
enabled = false
}
@RequiredArgsConstructor
@Configuration
public class QueryDSLConfig {
@PersistenceContext
private final EntityManager em;
sd
@Bean
public JPAQueryFactory queryFactory(){
return new JPAQueryFactory(em);
}
}
그리고 빌드하는 과정에서 오류가 나서
그래들로 되어있는걸 인텔리제이로 변경하여 해결
@Override
public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page) {
//동적쿼리(gubun 값을 가지고 동적쿼리 = DEPOSIOT, WITHDRAW, ALL)
//JPQL
String sql = "";
sql += "select t from Transaction t ";
if(gubun.equals("WITHDRAW")){
sql += "join fetch t.withdrawAccount wa "; //fetch를 지우면 join 해서 데이터를 끌고왔지만 조회는 안한다.
sql += "where t.withdrawAccount.id = :withdrawAccountId";
}else if(gubun.equals("DEPOSIT")){
sql += "join fetch t.depositAccount da ";
sql += "where t.depositAccount.id = :depositAccountId";
}else { //gubun = all
sql += "left join t.withdrawAccount wa "; //left 뺴면 null값은 조회 안한다 1345
sql += "left join t.depositAccount da "; // left 빼면 345가 나옴 두번쨰 테이블의 1번이 null이라서
sql += "where t.withdrawAccount.id = :withdrawAccountId ";
sql += "or ";
sql += "t.depositAccount.id = :depositAccountId";
}
TypedQuery<Transaction> query = em.createQuery(sql, Transaction.class); //jpql문법
if(gubun.equals("WITHDRAW")){
query = query.setParameter("withdrawAccountId", accountId);
}else if(gubun.equals("DEPOSIT")){
query = query.setParameter("depositAccountId", accountId);
}else{
query = query.setParameter("withdrawAccountId", accountId);
query = query.setParameter("depositAccountId", accountId);
}
query.setFirstResult(page*5); // 5, 10, 15
query.setMaxResults(5);
return query.getResultList();
}
@Override
public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page) {
JPAQuery<Transaction> query = jpaQueryFactory.selectFrom(transaction);
if ("WITHDRAW".equals(gubun)) {
query
.innerJoin(transaction.withdrawAccount, QAccount.account)
.fetchJoin()
.where(withDrawEq(accountId));
} else if ("DEPOSIT".equals(gubun)) {
query
.innerJoin(transaction.depositAccount, QAccount.account)
.fetchJoin()
.where(depositEq(accountId));
} else { // gubun = all
query
.leftJoin(transaction.withdrawAccount, QAccount.account)
.leftJoin(transaction.depositAccount, QAccount.account)
.where(allEq(accountId));
}
return query
.offset(page * 5)
.limit(5)
.fetch();
}
private BooleanExpression withDrawEq(Long accountId) {
return accountId != null ? transaction.withdrawAccount.id.eq(accountId): null;
}
private BooleanExpression depositEq(Long accountId) {
return accountId != null ? transaction.depositAccount.id.eq(accountId): null;
}
private BooleanExpression allEq(Long accountId) {
return accountId != null ? transaction.withdrawAccount.id.eq(accountId).or(transaction.depositAccount.id.eq(accountId)): null;
}
if else 로 구분 지은 다음에 where 절 안의 쿼리를 booleanExpression을 사용하였습니다.