EntityListener
1
2
3
4
5
6
7
@PrePersist
@PostPersist
@PreUpdate
@PostUpdate
@PreRemove
@PostRemove
@PostLoad
AttributeConverter
1
2
3
4
5
6
7
8
9
10
11
12
13
@Converter
class SnackNutrientConverter : AttributeConverter<SnackNutrient, String> {
private val mapper = jacksonObjectMapper()
override fun convertToDatabaseColumn(attribute: SnackNutrient): String {
return mapper.writeValueAsString(attribute)
}
override fun convertToEntityAttribute(dbData: String): SnackNutrient {
return mapper.readValue(dbData)
}
}
Spring Data JPA
Repository 커스텀, 확장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface SnackRepositoryCustom {
fun findBy(name: String): Snack?
}
@Repository
@Transactional
class SnackRepositoryCustomImpl(private val em: EntityManager) : SnackRepositoryCustom {
override fun findBy(name: String): Snack? {
return em.createQuery("SELECT s FROM Snack s WHERE s.name = :name", Snack::class.java)
.setParameter("name", name)
.resultList.firstOrNull()
}
}
기본 Repository 커스텀
1
2
3
4
5
interface MyRepo<T, ID> : JpaRepository<T, ID>
class MyRepoImpl<T, ID>() : MyRepo<T, ID>, SimpleJpaRepository<T, ID>()
@EnableJpaRepositories(repositoryBaseClass = MyRepoImpl::class)
Querydsl
의존성 및 어노테이션 프로세서 추가
1
2
implementation("com.querydsl:querydsl-jpa")
kapt("com.querydsl:querydsl-apt:4.2.1:jpa")
QDomain 생성
1
./gradlew kaptKotlin -i -S
기본 사용법
1
2
3
4
5
6
val car = QCar.car
val query = JPAQuery<Car>(em)
val result = query.from(car)
.where(car.name.eq("asd"))
.fetch()
Spring Data JPA와 Querydsl 함께 사용하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Transactional
class SnackRepositoryCustomImpl : SnackRepositoryCustom, QuerydslRepositorySupport(Snack::class.java) {
override fun findBy(name: String): Snack? {
return entityManager!!.createQuery("SELECT s FROM Snack s WHERE s.name = :name", Snack::class.java)
.setParameter("name", name)
.resultList.firstOrNull()
}
override fun findAllBy(name: String): List<Snack> {
val snack = QSnack.snack
return from(snack)
.where(snack.name.eq(name))
.fetch()
}
}