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

如何用Hibernate Criteria实现指定SQL关联查询?

使用Hibernate Criteria实现指定SQL查询

首先,先明确你的原SQL逻辑:查询所有关联了状态为0或1的许可证的用户,并且返回去重的用户记录。接下来我帮你修正Hibernate Criteria的实现,同时分析你现有代码的问题。

你的代码存在的问题

你当前的代码用了Projection来指定返回的属性,这会导致查询结果是Object[]数组(包含user.idUtilisateur和licence.utilisateur),而不是你需要的Utilisateur实体对象;另外也没有添加许可证状态的过滤条件,也没处理去重逻辑,所以达不到原SQL的效果。

正确的实现代码

下面是匹配原SQL逻辑的Hibernate Criteria写法:

Session session = this.sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Utilisateur.class, "user")
    // 内连接关联licence集合,对应原SQL的INNER JOIN
    .createAlias("user.listeLicence", "licence")
    // 添加许可证状态条件:activation为0或1,对应原SQL的WHERE子句
    .add(Restrictions.in("licence.activation", Arrays.asList(0, 1)))
    // 去重,对应原SQL的DISTINCT
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

List<Utilisateur> liste = criteria.list();

代码解释

  • createAlias:用于建立实体间的关联,这里等同于SQL的INNER JOIN(Hibernate Criteria默认内连接),关联Utilisateur的listeLicence集合到别名licence。
  • Restrictions.in:替代原SQL的OR条件,更简洁地匹配activation为0或1的情况。
  • setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY):确保返回的Utilisateur对象是去重的,对应原SQL的DISTINCT关键字,避免因为一个用户有多个符合条件的许可证而返回重复的用户实例。

如果你更倾向于用createCriteria来关联(和你原代码的写法接近),也可以这样写:

Criteria criteria = session.createCriteria(Utilisateur.class, "user")
    .createCriteria("user.listeLicence", "licence")
    .add(Restrictions.in("licence.activation", Arrays.asList(0, 1)))
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

List<Utilisateur> liste = criteria.list();

这两种写法的效果是一致的,createAlias更适合只需要关联过滤而不需要对关联实体做更多查询的场景,createCriteria则可以对关联实体添加更多的嵌套条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:57:34