我正在尝试仅获取max(assetHistoryId),但我的下面的代码在结果中将3列max(assetHistoryId),eventId和assetIdentifier撤回。 如何使用条件对列进行分组。 你可以在下面找到我的代码。
final Criteria agcriteria = createCriteria(someclass.class);
agcriteria.add(Restrictions.in("eventId", listOfEventIds));
agcriteria.add(Restrictions.ne("action", "T"));
agcriteria.add(
Restrictions.between("modifyDate", lastProcessedTime,
batchStartTime));
agcriteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("assetIdentifier"))
.add(Projections.groupProperty("eventId"))
.add(Projections.max("assetHistoryId")));
val = agcriteria.list();
请帮帮我吗?
答案 0 :(得分:0)
如果我理解正确,您只需要max(assetHistoryId)而不需要任何其他列详细信息。 你可以尝试这样的事情:
Criteria agcriteria = createCriteria(someclass.class);
agcriteria.setProjection(Projections.projectionList()
.add(Projections.max("assetHistoryId")));
你可以添加限制,如果有的话......这样:agcriteria.add(Criteria c);
或同一组条件
agcriteria.add(Restrictions.in("eventId", listOfEventIds));
agcriteria.add(Restrictions.ne("action", "T"));
agcriteria.add(
Restrictions.between("modifyDate", lastProcessedTime,
batchStartTime));
答案 1 :(得分:0)
好吧,男孩和女孩。我知道这是一种坏事,而Hibernate Criteria Api很久以前就已弃用。但是仍然有一些系统使用此API,因此希望它会有用。
我找不到使用内置的冬眠投影的方法,因此我决定自己制作一个。首先,我们需要创建一个新的投影类,该类不会在SELECT子句中产生任何结果,但是在group子句中仍然有它。
public class NoPropertyGroupProjection extends SimpleProjection {
private String propertyName;
protected NoPropertyGroupProjection(String propertyName) {
this.propertyName = propertyName;
}
@Override
public boolean isGrouped() {
return true;
}
@Override
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new Type[] { };
}
@Override
public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
return "";
}
@Override
public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return StringHelper.join( ", ", criteriaQuery.getColumns( propertyName, criteria ) );
}
@Override
public String toString() {
return propertyName;
}
}
那是我所拥有的Hibernate版本的PropertyProjection的副本,但有一些更改。
它不能单独工作(强制它单独工作非常复杂),但是在大多数情况下,我们仍然需要选择一些东西。
因此,我们接下来需要修复ProjectionList,因为它将以空列中断,我们正在尝试将其传递。所以,这是下一堂课。可耻的元素列表是私人的,但是我们有足够的吸气剂来实现我们的目标。
public class ProjectionListWithOnlyGroupBySupport extends ProjectionList {
@Override
public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException {
final StringBuilder buf = new StringBuilder();
String separator = "";
for ( int i = 0; i < this.getLength(); i++ ) {
Projection projection = this.getProjection(i);
String addition = projection.toSqlString( criteria, loc, criteriaQuery );
if (!"".equals(addition)) {
buf.append(separator).append(addition);
loc += getColumnAliases(loc, criteria, criteriaQuery, projection).length;
separator = ", ";
}
}
return buf.toString();
}
private static String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery, Projection projection) {
return projection instanceof EnhancedProjection
? ( (EnhancedProjection) projection ).getColumnAliases( loc, criteria, criteriaQuery )
: projection.getColumnAliases( loc );
}
}
同样,对原始班级进行细微调整。现在,我们拥有完成目标所需的一切。但是为了方便起见,我们将再创建一个类。
public final class AdvancedProjections {
public static NoPropertyGroupProjection groupBy(String propertyName) {
return new NoPropertyGroupProjection( propertyName );
}
public static ProjectionList projectionList() {
return new ProjectionListWithOnlyGroupBySupport();
}
}
创建所有这些类之后,我们可以更改问题中的代码:
final Criteria agcriteria = createCriteria(someclass.class);
agcriteria.add(Restrictions.in("eventId", listOfEventIds));
agcriteria.add(Restrictions.ne("action", "T"));
agcriteria.add(
Restrictions.between("modifyDate", lastProcessedTime,
batchStartTime));
agcriteria.setProjection(AdvancedProjections.projectionList()
.add(Projections.max("assetHistoryId"))
.add(AdvancedProjections.groupBy("assetIdentifier"))
.add(AdvancedProjections.groupBy("eventId")));
val = agcriteria.list();
Voila!