我有这个任务库:
@Repository
interface MissionRepository: CrudRepository<MissionEntity, String>, JpaSpecificationExecutor<MissionEntity>
在我的任务服务课中,我想获取所有具有给定参数countryId
的Set
部分的任务:
fun findAllByCountryIdIn(countryIds: Set<String>): List<MissionEntity> =
missionRepository.findAll(where(countryIdIn(countryIds)))
}
countryIdIn
(使用in
谓词)来自:
class MissionSpecifications {
companion object {
fun countryIdIn(countryIds: Set<String>): Specification<MissionEntity> =
Specification { root, _, _ -> root.get<String>("countryId").`in`(countryIds) }
}
}
但是当Set
为空时,我得到了一个可预测的sql错误。有没有办法只在给定集合不为空时激活where子句?没有if / else检查?也许我的规范语法可以改进,以避免这个SQL错误?
我宁愿早点回来。因此,如果您不首先需要它,请不要添加。您可以通过多种方式实现这一目标,例如使用takeIf
,简单的if
,when
等。
只列出一些样品:
takeIf
fun findAllByCountryIdIn(countryIds: Set<String>) = countryIds.takeIf { it.isNotEmpty() }
?.let { missionRepository.findAll(where(countryIdIn(it))) }
?: // what should be returned otherwise? emptyList? all? exception?
ifEmpty
(Kotlin >=1.3)
fun findAllByCountryIdIn(countryIds: Set<String>) = countryIds.ifEmpty {
// what should be returned? emptyList? all entries?
}.let {
missionRepository.findAll(where(countryIdIn(it))) }
}
if
fun findAllByCountryIdIn(countryIds: Set<String>) = if (countryIds.isEmpty()) /* what should be returned? */
else missionRepository.findAll(where(countryIdIn(countryIds))) }
如果你只是解决了countryIdIn
,例如通过传递一个空元素,您可以将查询本身的控制权交给helper方法。如果你真的想那么,那很好......但是否则我不会这样做。
为什么我不这样做?如果我稍后返回到该特定代码并阅读findAll(where(countryIdIn(countryIds)))
。如果集合为空,我需要多长时间理解我会返回所有条目?事实是:我不能不看countryIdIn
本身。但这是我的意见。
如果集合为空,只需在创建Specification
的函数中进行测试,如果是,则返回一个空的Specification
。
另一个解决方案是:
@Repository
interface MissionRepository: JpaRepository<MissionEntity, String> {
fun findByCountryIdIn(countryIds: Set<String>, pageable: Pageable): Page<MissionEntity>
}
你可以在哪里添加分页。