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

如何用Hibernate Criteria去除同COLOR属性重复的对象?

实现方案

方法一:子查询分组+主查询匹配(兼容性最优)

核心思路是先通过子查询获取每个color对应的唯一标识(比如最小的id),再基于这些标识查询完整的User对象,确保每个color只返回一条数据。

代码示例:

// 子查询:按color分组,取每组最小的id(也可换成max,按需选择保留哪条数据)
DetachedCriteria subQuery = DetachedCriteria.forClass(User.class)
    .setProjection(Projections.projectionList()
        .add(Projections.min("id"))
        .add(Projections.groupProperty("color")));

// 主查询:筛选id在子查询结果中的User
Criteria criteria = SrvDataAccess.getCurrentSession().createCriteria(User.class)
    .add(Subqueries.propertyIn("id", subQuery));

List<User> result = criteria.list();

方法二:Distinct投影+结果转换(Hibernate 5.2+适用)

如果你的Hibernate版本在5.2及以上,可以直接通过投影指定所有需要返回的字段,配合distinct去重,再转成User实体。

代码示例:

Criteria criteria = SrvDataAccess.getCurrentSession().createCriteria(User.class)
    .setProjection(Projections.distinct(Projections.projectionList()
        .add(Projections.property("id"), "id")
        .add(Projections.property("name"), "name")
        .add(Projections.property("age"), "age")
        .add(Projections.property("color"), "color")))
    .setResultTransformer(Transformers.aliasToBean(User.class));

List<User> result = criteria.list();

注意:必须把所有需要返回的字段都加入投影,否则实体属性会缺失;不同数据库对多字段distinct的处理有差异,需要测试验证。

方法三:HQL辅助实现(可选补充)

如果觉得Criteria写法繁琐,也可以用HQL实现相同逻辑,思路和方法一一致:

String hql = "SELECT u FROM User u WHERE u.id IN (SELECT MIN(u2.id) FROM User u2 GROUP BY u2.color)";
List<User> result = SrvDataAccess.getCurrentSession().createQuery(hql, User.class).list();

额外说明

  • 方法一的兼容性最好,适配绝大多数Hibernate版本,且不会出现属性丢失问题,优先推荐。
  • 选择MIN(id)还是MAX(id),取决于你想保留每组中的哪一条数据(比如id自增的话,MIN对应最早创建的记录,MAX对应最新的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:36:43