空列表时表达式`in`(弹簧数据jpa规范)

问题描述 投票:0回答:3

我有这个任务库:

@Repository
interface MissionRepository: CrudRepository<MissionEntity, String>, JpaSpecificationExecutor<MissionEntity>

在我的任务服务课中,我想获取所有具有给定参数countryIdSet部分的任务:

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错误?

jpa kotlin spring-data-jpa jpql
3个回答
1
投票

我宁愿早点回来。因此,如果您不首先需要它,请不要添加。您可以通过多种方式实现这一目标,例如使用takeIf,简单的ifwhen等。

只列出一些样品:

  • 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本身。但这是我的意见。


0
投票

如果集合为空,只需在创建Specification的函数中进行测试,如果是,则返回一个空的Specification


0
投票

另一个解决方案是:

@Repository
interface MissionRepository: JpaRepository<MissionEntity, String> {
    fun findByCountryIdIn(countryIds: Set<String>, pageable: Pageable): Page<MissionEntity>
}

你可以在哪里添加分页。

© www.soinside.com 2019 - 2024. All rights reserved.