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

如何将含子查询的SQL转换为Hibernate Criteria查询?

Hibernate Criteria实现带子查询的SQL转换

原SQL核心逻辑

你需要实现的是:筛选出service_code匹配指定模式的记录,并且仅保留每个service_code对应**最新S_STARTDATE**的条目,最后按service_code和S_STARTDATE排序。

完整Criteria实现代码

结合你的实体类和需求,修改后的代码如下:

// 1. 创建主Criteria,关联实体类
Criteria criteria = this.getSession().createCriteria(BillingProductBaseView.class, "vsic");

// 2. 处理ids参数:多个serviceCode的like条件(OR逻辑)
if (!ids.isEmpty()) {
    Disjunction disjunction = Restrictions.disjunction();
    for (String id : ids) {
        disjunction.add(Restrictions.like("vsic.serviceCode", id));
    }
    criteria.add(disjunction);
}

// 3. 构建子查询:查询每个serviceCode对应的最大sStartDate
DetachedCriteria maxStartDateSubquery = DetachedCriteria.forClass(BillingProductBaseView.class, "sub")
        .setProjection(Projections.max("sub.sStartDate"))
        .add(Restrictions.eqProperty("sub.serviceCode", "vsic.serviceCode")); // 关联主查询的serviceCode

// 4. 添加子查询条件:主查询的sStartDate等于子查询的最大值
criteria.add(Restrictions.eqProperty("vsic.sStartDate", maxStartDateSubquery));

// 5. 设置投影(按需选择需要返回的字段)
criteria.setProjection(Projections.projectionList()
        .add(Projections.property("vsic.serviceCode"), "serviceCode")
        .add(Projections.property("vsic.serviceVersion"), "serviceVersion")
        .add(Projections.property("vsic.sStartDate"), "sStartDate"));

// 6. 设置结果转换器,将投影结果映射到实体类
criteria.setResultTransformer(Transformers.aliasToBean(BillingProductBaseView.class));

// 7. 添加排序规则
criteria.addOrder(Order.asc("vsic.serviceCode"));
criteria.addOrder(Order.asc("vsic.sStartDate"));

// 8. 执行查询
List<BillingProductBaseView> billingProductOfferingViewList = criteria.list();

关键部分说明

  • 多条件OR处理:原代码循环添加Restrictions.like会生成多个AND条件,不符合需求,改用Disjunction实现多个LIKE的OR逻辑。
  • 子查询实现:用DetachedCriteria构建子查询,通过eqProperty关联主查询和子查询的serviceCode,确保每个serviceCode取自身的最大S_STARTDATE。
  • 投影与结果转换:明确指定需要返回的字段,避免查询冗余数据,Transformers.aliasToBean用于将投影结果映射到实体类(注意实体类字段名要和投影别名一致)。
  • 排序:添加Order.asc实现原SQL的排序规则。

注意事项

如果你的实体类中包含v_end_date对应的字段(比如vEndDate),只需在投影中添加Projections.property("vsic.vEndDate"), "vEndDate"即可。

内容的提问来源于stack exchange,提问作者batman35

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:55:32