[JPA] SpringBoot(2.x version)์ QueryDsl JPA ์ ์ฉ (gradle ์ค์ )
QueryDsl์ SQL, JPQL ๋ฑ์ ์ฝ๋๋ก ์์ฑํ ์ ์๊ฒ ํ๋ builder opensource framework ์ด๋ค.
: ์ฌ๋์ด Query๋ฅผ ์ง๋ค๋ณด๋ฉด ๋ณดํต ์์์ ์ผ๋ก ํ๊ธฐ์ ์ค๋ฅ๊ฐ ์๊ธธ ์ฌ์ง๊ฐ ์๋๋ฐ (String์ด๋ค ๋ณด๋)
์ปดํ์ผ ๋จ๊ณ์์ ์ค๋ฅ๊ฐ ์๋์ง ์ ์ ์๋ค.
QueryDsl์ Query ์์ฑ์ ์๋ํ ํ์ฌ ์๋ฐ ์ฝ๋๋ก ์์ฑํ๋ฏ๋ก, ์์ ๊ฐ์ ๋ฌธ์ ์ ๋์ํ ์ ์๊ณ
๋ณต์กํ ์ฟผ๋ฆฌ๋ ๋์ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌํํ๋๋ฐ์ ์์ด ํ๊ณ๊ฐ ์๋ ์์ JPA๋ฅผ ๋ณด์ํ๊ธฐ ์ํด์๋ ์ฌ์ฉํ๋ค.
์์ง ์ค๋ฌด์์ ์ฐ๊ณ ์์ง๋ ์์ผ๋, ์ค๋ฌด์ ๋ง์ด ์ ์ฉํ๋ค๊ณ ํด์ ์๊ฒ๋๋ง ํ๋ณด์๋ค.
1. build.gradle ์ ํ
dependencies {
...
//querydsl
implementation 'com.querydsl:querydsl-jpa'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}
//querydsl option
// querydsl QClass ํ์ผ ์์ฑ ์์น๋ฅผ ์ง์
// def generated = "$buildDir/generated/querydsl"
def generated = 'src/main/generated'
tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
}
// java source set Qclass ์์น ์ถ๊ฐ
sourceSets {
main.java.srcDirs += [ generated ]
}
// gradle clean ์, QClass ๋๋ ํ ๋ฆฌ ์ญ์
clean {
delete file(generated)
}
: gradle ์ค์ ํ, gradle clean > gradle build > gradle compileJava ์์ผ๋ก ์คํ
๊ทธ๋ผ generated ์ ์ ์ํ ์์น์ ์๋ก์ด ๋๋ ํ ๋ฆฌ์ ํจ๊ป Qclass ํ์ผ์ด ์์ฑ๋๋ค.
Qclass๋ Entity๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋๋ฉฐ
JPAAnnotationProcessor๊ฐ ์ปดํ์ผ ์์ ์ @Entity ๋ฑ์ ์ด๋ ธํ ์ด์ ์ ์ฐพ์ ๋ถ์ํด ๋ง๋ ๋ค.
(์ํฐํฐ์ ๋์ผํ ํ์ผ ๋ช ์์ Q๊ฐ ๋ถ์ด์๋ค.)
QueryDsl์ ์ฟผ๋ฆฌ ์์ฑ ์, ์ด๋ฌํ Qclass๋ฅผ ๊ธฐ๋ฐ์ผ๋ก Query๋ฅผ ์คํํ๋ค.
2. Config ์ค์
@Configuration
public class QueryDslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() { return new JPAQueryFactory(entityManager); }
}
: JPAQueryFactory๋ฅผ Bean์ผ๋ก ๋ฑ๋กํด ํ๋ก์ ํธ ์ ์ญ์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ค.
โ JPAQueryFactory ๊ฐ์ฒด๊ฐ import ๋์ง ์์์ ๊ณ ์์ ๋ง์ด ํ๋๋ฐ intellij ์บ์ ์ญ์ ํ๋๊น ๊น๋ํ๊ฒ ํด๊ฒฐ๋๋ค ;;;;
๋ด์๊ฐ ๋๋ ค์ค์ ;;; ๋์ผ ๋ฌธ์ ๋ฐ์ ์, File > invalidate Caches ๋ฅผ ๋๋ฌ ์บ์ ์ญ์ ํ๊ธฐ
3. .gitignore ์ค์ (๋๋ ํ ๋ฆฌ๊ฐ $buildDir/generated/querydsl์ธ ๊ฒฝ์ฐ ํจ์ค)
: build.gradle ํ์ผ์์ "$buildDir/generated/querydsl" ๋ก ๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํด์ฃผ์์ผ๋ฉด ์๊ด์์ผ๋
(build ๋ฃจํธ๋ ์ ์ด์ .gitignore์ ์ค์ ๋์ด ์์)
๋์ ๊ฒฝ์ฐ์๋ build ๋ฃจํธ๋ก ๋ง๋ค๋ฉด Qclass๊ฐ ์ ๋๋ก import๋์ง ์์์, src ์๋์ ํด๋๋ฅผ ๋ง๋ค๋๋ก ํ๋ค.
.gitignore์ ์ถ๊ฐํ์ฌ ๋ฒ์ ๊ด๋ฆฌ๊ฐ ๋์ง ์๋๋ก ํ๋ค.
/src/main/generated/
๊ทธ๋ผ ์ด์ ๊ธฐ๋ณธ์ ์ธ ์ ํ ์ ๋๋ฌ์ผ๋ ๊ฐ๋จํ ์์ ๋ก ํ ์คํธ๋ฅผ ํด๋ณด์ !
SELECT * FROM TEST WHERE FIELD_1 IN ('ํ ์คํธ1', 'ํ ์คํธ2');
0. Entity
@Entity
@Getter
@Setter
@Table(name = "testTable")
public class Test {
@Id
@column(name = "field_1")
private String field1;
}
1. Controller์ ํ ์คํธ์ฉ ์กฐํ API ์ถ๊ฐ
@PostMapping("/Test")
public ResponseEntity select(@RequestBody String[] arr) {
return new ResponseEntity(service.select(arr), HttpStatus.OK);
}
2. Service
public List<Test> select(String[] arr) {
List<Test> rslt = testRepo.findByField1(arr);
return rslt;
}
3. Repository
@Repository
public interface TestRepo extends JpaRepository<Test>, TestRepoCustom {
}
4. RepositoryCustom
public interface TestRepoCustom {
List<Test> findByField1(String[] arr);
}
5. RepositoryImpl
@RequiredArgsConstructor
public class TestRepoImpl implements TestRepoCustom {
private final JPAQueryFactory jpaQueryFactory;
@Override
public List<Test> findByField1(String[] arr) {
return jpaQueryFactory
.selectFrom(test)
.where(test.field1.in(arr))
.fetch();
}
}