簡體   English   中英

如何在休眠條件中按沒有投影的列進行分組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM