如何用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
相关产品推荐
相关产品推荐

