728x90

QueryDSL 방식의 코드를 JOOQ 코드로 변경하는 방법으로 테스트하고 적어둔다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
@Service
@Transactional
@Log4j2
@RequiredArgsConstructor // 생성자 자동 주입
public class TodoSearchImpl implements TodoSearch {
 
    private final DSLContext dsl;
 
    @Override
    public Page<Todo> search1(PageRequestDTO pageRequestDTO) {
 
        String keyword = pageRequestDTO.getFilter().getKeyword();
        String where = pageRequestDTO.getFilter().getWhere();
 
        Condition condition = DSL.trueCondition();
 
        // 검색 조건 적용
        if (keyword != null && !keyword.trim().isEmpty()) {
            switch (where) {
                case "title":
                    condition = condition.and(TLB_TODO.TITLE.likeIgnoreCase("%" + keyword + "%"));
                    break;
                case "writer":
                    condition = condition.and(TLB_TODO.WRITER.likeIgnoreCase("%" + keyword + "%"));
                    break;
                default:
                    condition = condition.and(
                            TLB_TODO.TITLE.likeIgnoreCase("%" + keyword + "%")
                                    .or(TLB_TODO.WRITER.likeIgnoreCase("%" + keyword + "%"))
                    );
            }
        }
 
        Pageable pageable = PageRequest.of(
                pageRequestDTO.getPage() - 1,
                pageRequestDTO.getSize(),
                Sort.by("tno").descending()
        );
 
        // 실제 데이터 조회
        List<Todo> content = dsl.selectFrom(TLB_TODO)
                .where(condition)
                .orderBy(TLB_TODO.TNO.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch()
                .map(record -> Todo.builder()
                        .tno(record.getTno())
                        .title(record.getTitle())
                        .writer(record.getWriter())
                        .complete(record.getComplete())
                        .dueDate(record.getDueDate())
                        .build());
 
        long totalCount = dsl.selectCount()
                .from(TLB_TODO)
                .where(condition)
                .fetchOne(0, Long.class);
 
        return new PageImpl<>(content, pageable, totalCount);
    }
}
 

 

 

JOOQ Config

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import javax.sql.DataSource;
 
@Configuration
public class JooqConfig {
 
    @Bean
    public DSLContext dslContext(DataSource dataSource) {
        return DSL.using(dataSource, SQLDialect.MARIADB); // DB에 맞게
    }
}
 

 

 

build.gradle

QueryDSL 과 JOOQ 혼용 테스트를 위해서 2가지 모두 처리할 수 있도록 구성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.4'
    id 'io.spring.dependency-management' version '1.1.7'
    id 'nu.studer.jooq' version '8.2' // JOOQ용 플러그인
}
 
group = 'com.mansa.smartx.api'
version = '0.0.1-SNAPSHOT'
 
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}
 
configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
 
repositories {
    mavenCentral()
}
 
ext {
    querydslDir = "$buildDir/generated/querydsl"
    jooqDir = "$buildDir/generated-src/jooq"
}
 
sourceSets {
    main {
        java {
            srcDir querydslDir
            srcDir jooqDir
        }
    }
}
 
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.thymeleaf.extras:thymeleaf-extras-springsecurity6'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.projectlombok:lombok'
 
    implementation 'org.modelmapper:modelmapper:3.2.2'
 
    //QueryDSL 추가
    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
    annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
    annotationProcessor "jakarta.annotation:jakarta.annotation-api"
    annotationProcessor "jakarta.persistence:jakarta.persistence-api"
 
    // JOOQ
    implementation "org.jooq:jooq:3.19.7"
    jooqGenerator "org.jooq:jooq-codegen:3.19.7"
    jooqGenerator "org.mariadb.jdbc:mariadb-java-client" 
 
    implementation 'net.coobird:thumbnailator:0.4.20'
 
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'com.google.code.gson:gson:2.12.1'
 
    implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
    implementation 'io.jsonwebtoken:jjwt-impl:0.12.6'
    implementation 'io.jsonwebtoken:jjwt-jackson:0.12.6'
 
    implementation 'org.springframework.boot:spring-boot-starter-validation'
 
    // P6Spy
//    implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'
    implementation 'org.hibernate.orm:hibernate-core:6.6.12.Final' // 최신 버전
 
    // Redis
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
 
    //test 롬복 사용
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    testImplementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
 
}
 
tasks.named('compileJava', JavaCompile).configure {
    options.annotationProcessorGeneratedSourcesDirectory = file(querydslDir)
}
 
tasks.named('test') {
    useJUnitPlatform()
}
 
tasks.named('clean') {
    delete querydslDir
    delete jooqDir
}
 
jooq {
    version = '3.19.7'
    configurations {
        main {
            generationTool {
                jdbc {
                    driver = 'org.mariadb.jdbc.Driver' // 또는 PostgreSQL
                    url = 'jdbc:mariadb://localhost:3306/malldb'
                    user = 'testfox'
                    password = 'TestCodefox!!'
                }
                generator {
                    database {
                        name = 'org.jooq.meta.mariadb.MariaDBDatabase' // 또는 postgres
                        inputSchema = 'malldb' // 보통 'yourdb'
                        includes = '.*'
                    }
                    generate {
                        deprecated = false
                        records = true
                        immutablePojos = true
                        fluentSetters = true
                    }
                    target {
                        packageName = 'com.jpashop.api.jooq.generated'
                        directory = jooqDir
                    }
                }
            }
        }
    }
}
 
 

 

 

 

 

 

728x90
블로그 이미지

Link2Me

,