基于Spring Hibernate/JPA如何实现多列多匹配条件查询
解决方案
方案1:直接使用JPA多列IN查询(优先推荐,实现成本最低)
只要你用的是Hibernate 5.1及以上版本作为JPA实现,且底层数据库支持行值表达式(MySQL 5.7+、PostgreSQL、Oracle、SQL Server 2008+等主流数据库都支持),原来的写法只需要调整参数类型就能直接跑:
@Query(""" select s from SampleTable s where (s.a, s.b, s.c, s.d) in :criterias """) fun selectByMultipleCriteria(criterias: List<Array<String>>): List<SampleTable>
调用的时候把每组匹配条件转成字符串数组传入就行:
val criteriaList = listOf( arrayOf("a value 1", "b value 1", "c value 1", "d value 1"), arrayOf("a value 2", "b value 2", "c value 2", "d value 2") ) val result = sampleRepository.selectByMultipleCriteria(criteriaList)
方案2:原生SQL实现
如果遇到JPQL兼容问题,直接写原生SQL开启原生查询即可,逻辑和上面完全一致:
@Query( value = "select * from sample_table where (a, b, c, d) in :criterias", nativeQuery = true ) fun selectByMultipleCriteriaNative(criterias: List<Array<String>>): List<SampleTable>
方案3:不支持行值表达式的兼容方案
如果用的数据库非常老旧不支持行值表达式,可以用OR拼接多组条件,不需要写复杂的Specification:
如果条件数量固定,直接写死就行:
@Query(""" select s from SampleTable s where (s.a = ?1 and s.b = ?2 and s.c = ?3 and s.d = ?4) or (s.a = ?5 and s.b = ?6 and s.c = ?7 and s.d = ?8) -- 按实际条件数量追加即可 """)
如果条件数量不固定,用简单的字符串拼接生成JPQL,再通过EntityManager执行就行,实现复杂度比Specification低很多。
注意事项
- 若匹配条件组数超过数据库IN语句的参数上限(比如Oracle的IN参数上限是1000),建议把条件分批查询后合并结果。
- Kotlin里不要直接传Triple、自定义data class等类型作为参数,统一转成数组就能避免参数绑定错误。
内容的提问来源于stack exchange,提问作者Ferdia Fagan
相关产品推荐
相关产品推荐

