@Repository
abstract class CustomQuerydslRepositorySupport (domainClass: Class<*>?) : QuerydslRepositorySupport(domainClass!!) {
@PersistenceContext
override fun setEntityManager(entityManager: EntityManager) {
super.setEntityManager(entityManager)
}
}
@RestController
@RequestMapping("/${Application.VERSION}/area")
class AreaEndpoint(private val areaCommand: AreaCommand) {
@GetMapping
fun getAreas(areaReqeust: AreaReqeust, @PageableDefault(size = 30, page = 0, sort = ["id"], direction = Sort.Direction.DESC) pageable: Pageable): ResponseEntity<Page<Area>> {
return ResponseEntity.ok(areaCommand.getAreas(areaReqeust, pageable))
}
data class AreaReqeust(
override val id: Long? = null,
override val city: String? = null,
override val district: String? = null,
override val deposit: Long? = null,
override val rentalPrice: Long? = null,
override val managementCost: Long? = null,
override val areaWeighted: Long? = null,
override val createdAt: LocalDateTime? = null,
override val updatedAt: LocalDateTime? = null,
) : Area
}
@Component
class AreaRepositoryAdaptor(
private val query: JPAQueryFactory,
) : CustomQuerydslRepositorySupport(AreaEntity::class.java), AreaQueryRepository {
override fun getAreas(areaRequest: Area, pageable: Pageable): Page<Area> = query
.selectFrom(area)
.applyFilter(areaRequest)
.let { baseQuery ->
val list = querydsl!!.applyPagination(pageable, baseQuery).fetch().map { it.toDto() }
val count = baseQuery.select(area.id.count()).fetchFirst() ?: 0L
PageableExecutionUtils.getPage(list, pageable) { count }
}
fun AreaEntity.toDto() = AreaResponse(
id = id,
city = city,
district = district,
deposit = deposit,
rentalPrice = rentalPrice,
managementCost = managementCost,
areaWeighted = areaWeighted,
createdAt = createdAt,
updatedAt = updatedAt,
)
private fun JPAQuery<AreaEntity>.applyFilter(areaRequest: Area): JPAQuery<AreaEntity> = where(
BooleanBuilder().apply {
areaRequest.run {
city?.let { and(area.city.eq(it)) }
district?.let { and(area.district.eq(it)) }
deposit?.let { and(area.deposit.eq(it)) }
rentalPrice?.let { and(area.rentalPrice.eq(it)) }
managementCost?.let { and(area.managementCost.eq(it)) }
areaWeighted?.let { and(area.areaWeighted.eq(it)) }
}
},
)
}
data class AreaResponse(
override val id: Long? = null,
override val city: String? = null,
override val district: String? = null,
override val deposit: Long? = null,
override val rentalPrice: Long? = null,
override val managementCost: Long? = null,
override val areaWeighted: Long? = null,
override val createdAt: LocalDateTime? = null,
override val updatedAt: LocalDateTime? = null,
) : Area