You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:27:14