如何使用Hibernate Criteria实现列转行表的多AND条件查询
用Hibernate Criteria实现EAV模型的多AND条件查询
这是典型的EAV(实体-属性-值)模型的多条件查询场景,要筛选出同时满足多个属性条件的Pk,我给你两种可行的实现方案:
方案一:使用子查询(DetachedCriteria)
通过多个子查询分别找出符合单个条件的Pk,再在主查询中取这些Pk的交集,就能得到同时满足所有条件的结果。
// 子查询1:获取EmpName为Sachin的所有Pk DetachedCriteria nameSubQuery = DetachedCriteria.forClass(Employee.class) .add(Restrictions.eq("columnName", "EmpName")) .add(Restrictions.eq("value", "Sachin")) .setProjection(Projections.property("pk")); // 子查询2:获取Empsalary为10,000的所有Pk DetachedCriteria salarySubQuery = DetachedCriteria.forClass(Employee.class) .add(Restrictions.eq("columnName", "Empsalary")) .add(Restrictions.eq("value", "10,000")) .setProjection(Projections.property("pk")); // 主查询:筛选同时出现在两个子查询结果中的Pk Criteria mainCriteria = session.createCriteria(Employee.class) .add(Subqueries.propertyIn("pk", nameSubQuery)) .add(Subqueries.propertyIn("pk", salarySubQuery)) .setProjection(Projections.distinct(Projections.property("pk"))); // 执行查询,得到预期的Pk=1 List<Integer> targetPks = mainCriteria.list();
这个方案逻辑清晰:每个子查询负责筛选符合单个条件的Pk,主查询通过propertyIn取交集,最后用distinct去重(因为同一个Pk会对应多条记录)。
方案二:使用分组+Having子句
先筛选出符合任意一个条件的记录,再按Pk分组,统计每个分组下符合条件的记录数,只有当统计数等于条件总数时,才说明该Pk满足所有条件。
Criteria criteria = session.createCriteria(Employee.class) // 先筛选出符合任意一个目标条件的记录 .add(Restrictions.or( Restrictions.and( Restrictions.eq("columnName", "EmpName"), Restrictions.eq("value", "Sachin") ), Restrictions.and( Restrictions.eq("columnName", "Empsalary"), Restrictions.eq("value", "10,000") ) )) // 按Pk分组,并统计每组的记录数 .setProjection(Projections.projectionList() .add(Projections.groupProperty("pk")) .add(Projections.rowCount(), "matchCount")) // 要求匹配的记录数等于条件总数(这里是2) .add(Restrictions.eq("matchCount", 2)); // 执行查询,得到结果 List<Integer> targetPks = criteria.list();
如果后续需要增加更多条件(比如再加一个EmpId的限制),只需要在or里新增对应的and条件,同时把matchCount的值改成条件的总数量即可。
注意事项
- 如果
value字段存储的是数值类型(比如薪资),建议使用对应类型的比较(比如Restrictions.eq("value", 10000)),避免字符串类型转换带来的问题。 - 两种方案可按需选择:子查询适合条件较少的情况,分组统计适合条件较多且性能要求较高的场景(前提是Pk和ColumnName字段有合适的索引)。
内容的提问来源于stack exchange,提问作者user9149924
相关产品推荐
相关产品推荐

