[Spring] QueryDSL Introduction ( w/ Spring Data JPA, Kotlin ) 공부/BE, DB

Date 2022. 2. 22. 15:11

Dependency

QueryDSL generates QClass that used to write typesafe query.
then, We should add annotation processor to generate QClass from entity.

 

plugins {
  ...
  kotlin("kapt") version "1.6.10"
}

dependencies {
  ...

  implementation("com.querydsl:querydsl-core")
  implementation("com.querydsl:querydsl-jpa")
  kapt(group = "com.querydsl", name = "querydsl-apt", classifier = "jpa")
  sourceSets.main {
        withConvention(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::class) {
            kotlin.srcDir("build/generated/source/kapt/main")
        }
  }
}

QueryDSL Configuration

To use QuerydslRepositorySupport after, We need JPAQueryFactory type Bean.

 

@Configuration
class QuerydslConfig(
    @PersistenceContext val entityManager: EntityManager
) {
  @Bean
  fun jpaQueryFactory() = JpaQueryFactory(entityManager)
}

 

If We have more than one datasource, We should qualify bean for disambiguation. ( Using @Qualifier Annotation ? )

Now Ready to use QuerydslRepositorySupport in Spring App.

Build : Generate QClass

 

gradle build

Predicate : QuerydslPredicateExecutor

 

Spring Data JPA supports QueryDSL Integration ( org.springframework.data.querydsl )

Using QuerydslPredicateExecutor interface, you can write typesafe query using Predicate.

QuerydslPredicateExecutor interface use Predicate to execution query.

For Example...

 

Optional<T> findOne(Predicate predicate)
Page<T> findAll(Predicate predicate, Pageable pageable)
Iterable<T> findAll(Predicate predicate, OrderSpecifier<?>... orders)

 

extends QuerydslPredicateExecutor interface

 

interface UserRepository: JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
  ...
}

 

then you can use Predicate in Repository.

 

fun findByUsername(username: String) {
    val predicate = QUser.user.username.like("%foo%")
    val pageable = PageRequest.of(page = 0, size = 10)
    val users = userRepository.findAll(predicate, pageable)
    users.forEach {
        it.username shouldContain "foo"
    }
}

QuerydslRepositorySupport : JpaQueryFactory

 

write complicate query in type-safe way.

 

You can write query without QuerydslRepositorySupport. just Inject JpaQueryFactory Bean.

@Repository
class UserRepositorySupport(
    @Autowired val query: JPAQueryFactory
): QuerydslRepositorySupport(User::class.java) {
  private val user = QUser.user

  fun findByUsername(username: String): User {
      val where = BooleanBuilder()
    where.and(user.username.like("%$username%")
    return query.select(user).from(user).where(where).fetchFirst()
  }
}

fetchFirst method shorten limit(1).fetchOne()

 

Recent Posts

Popular posts

Recent Comments

Tag List

테라폼 JavaScript ORM 인증 도커 백준 IAC 클라우드 TypeScript k8s API JWT DNS 컨테이너 네트워크 인가 알고리즘 네임스페이스 AWS GCP 운영체제 파이썬 리눅스 DB
Total : Today : Yesterday :
Blog powered by Tistory, Designed by hanarotg