提问人:instanceOfObject 提问时间:12/22/2012 最后编辑:instanceOfObject 更新时间:10/21/2023 访问量:9915
在 Hibernate 条件查询中选择带有 “Group BY” 的 “All Columns”
select "all columns" with "group by" in hibernate criteria queries
问:
我想使用“group by”编写一个条件查询,并希望返回所有列。
平面 sql 是这样的:
select * from Tab group by client_name order by creation_time;
我知道它将有行数。count(distinct client_name)
我目前的查询似乎没有给出正确的结果如下:
Criteria criteria = getSession(requestType).createCriteria(Tab.class);
criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("client_name")));
criteria.addOrder(Order.asc("creationTime"));
此查询仅返回。我不想手动输入所有列名。一定有办法,能做些什么?"client_name"
答:
我认为你误解了什么。如果使用 SQL,则需要按所有选定的列进行分组。这同样适用于 Hibernate - 如果你在一个 中,你就是在告诉 Hibernate 该列是一个组列。如果没有引用其他列/字段,Hibernate 会认为你不需要它们,因为它们也需要分组。GROUP BY
groupProperty
Projection
退后一步:你想做什么?如果表中的所有列都有重复数据,则可能是数据错误,或者数据保存不正确。至少,你的钥匙会搞砸。
在休眠状态下进行投影时,需要将所有需要的列添加到投影列表中。为了在实体中获取结果,我们必须使用 setResultTransformer。查看以下示例以在休眠状态中获取分组依据:
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.groupProperty("column1"));
projectionList.add(Projections.property("column2"));
projectionList.add(Projections.property("column3"));
criteria.setProjection(projectionList);
criteria.setResultTransformer(Transformers.aliasToBean(Table.class));
使用休眠投影时,您应该在投影列表中添加所有需要的列。您只使用了 Projections.projectionList().add(Projections.groupProperty(“client_name”))
这。所以很明显,回报只有client_name。
无法使用基于单个列的组来获取数据库的所有列。相反,您可以使用 group by 子句和 select 中的所有列。在休眠状态下获得结果,如下所示
Criteria criteria = getSession(requestType).createCriteria(Tab.class);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("client_name"));
projectionList.add(Projections.property("column2"));
projectionList.add(Projections.property("column3"));
projectionList.add(Projections.groupProperty("client_name"));
projectionList.add(Projections.groupProperty("column2"));
projectionList.add(Projections.groupProperty("column3"));
criteria.setProjection(projectionList);
criteria.addOrder(Order.asc("creationTime"));
您可以通过分配实体类和属性名称来实现此目的,然后动态过滤它们,如下所示:
Criteria criteria = getSession(requestType).createCriteria(Tab.class);
Class<?> entityClass = Tab.class;
String[] propertyNames = sessionFactory.getClassMetadata(entityClass).getPropertyNames();
criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("client_name")));
//skipping client_name as already added first
for (String propertyName : propertyNames) {
if (!"client_name".equals(propertyName)) {
criteria.add(Projections.groupProperty(propertyName));
}
}
// Add order by if needed
criteria.addOrder(Order.asc("creationTime"));
List<Object[]> result = criteria.list();
评论