![](/img/trans.png)
[英]Add a Group by to a Hibernate Criteria-Query without Projection
[英]how to group by columns without projection in hibernate criteria?
我試圖只獲取 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();
請幫助我任何人?
如果我理解正確,您只需要 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));
好吧,男孩和女孩。 我知道這是一個死靈,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 因為它會破壞我們試圖傳遞它的空列。 所以,這是下一節課。 Shame元素列表是私有的,但我們有足夠的 getter 來實現我們的目標。
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();
瞧!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.