空列表时的表达式“in”(spring 数据 jpa 规范)
Expression `in` when empty list (spring data jpa specification)
我有这个任务库:
@Repository
interface MissionRepository: CrudRepository<MissionEntity, String>, JpaSpecificationExecutor<MissionEntity>
在我的任务服务 class 中,我想获取所有具有给定参数 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 错误?
如果集合为空,只需在创建 Specification
的函数中进行测试,如果为空,则 return 一个空的 Specification
。
我宁愿return早一点。因此,如果您一开始不需要它,就不要添加 where 。您可以通过多种方式做到这一点,例如使用 takeIf
、简单的 if
、when
等
仅列出一些示例:
-
fun findAllByCountryIdIn(countryIds: Set<String>) = countryIds.takeIf { it.isNotEmpty() }
?.let { missionRepository.findAll(where(countryIdIn(it))) }
?: // what should be returned otherwise? emptyList? all? exception?
-
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
,例如通过传递一个空元素,您将查询本身的控制权交给了辅助方法。如果你真的想要那个,那好吧......但否则我不会那样做。
为什么我不这样做?如果我稍后 return 到该特定代码并阅读 findAll(where(countryIdIn(countryIds)))
。如果集合为空,我需要多长时间才能确定我 return 所有条目?事实是:我不能不看 countryIdIn
本身。但这是我的看法。
另一个解决方案是:
@Repository
interface MissionRepository: JpaRepository<MissionEntity, String> {
fun findByCountryIdIn(countryIds: Set<String>, pageable: Pageable): Page<MissionEntity>
}
在哪里可以添加分页。
我有这个任务库:
@Repository
interface MissionRepository: CrudRepository<MissionEntity, String>, JpaSpecificationExecutor<MissionEntity>
在我的任务服务 class 中,我想获取所有具有给定参数 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 错误?
如果集合为空,只需在创建 Specification
的函数中进行测试,如果为空,则 return 一个空的 Specification
。
我宁愿return早一点。因此,如果您一开始不需要它,就不要添加 where 。您可以通过多种方式做到这一点,例如使用 takeIf
、简单的 if
、when
等
仅列出一些示例:
-
fun findAllByCountryIdIn(countryIds: Set<String>) = countryIds.takeIf { it.isNotEmpty() } ?.let { missionRepository.findAll(where(countryIdIn(it))) } ?: // what should be returned otherwise? emptyList? all? exception?
-
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
,例如通过传递一个空元素,您将查询本身的控制权交给了辅助方法。如果你真的想要那个,那好吧......但否则我不会那样做。
为什么我不这样做?如果我稍后 return 到该特定代码并阅读 findAll(where(countryIdIn(countryIds)))
。如果集合为空,我需要多长时间才能确定我 return 所有条目?事实是:我不能不看 countryIdIn
本身。但这是我的看法。
另一个解决方案是:
@Repository
interface MissionRepository: JpaRepository<MissionEntity, String> {
fun findByCountryIdIn(countryIds: Set<String>, pageable: Pageable): Page<MissionEntity>
}
在哪里可以添加分页。