Hibernate条件使用GROUP BY和RETURN ENTITY LIST

cz_*_*esh 8 java hibernate criteria

我正在尝试GROUP BY按照我的标准使用.我需要这样做:

SELECT b FROM Book b GROUP BY volumeCode;
Run Code Online (Sandbox Code Playgroud)

我有以下代码:

    Criteria c = s.createCriteria(Book.class);
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
    List<Book> result = c.list();
Run Code Online (Sandbox Code Playgroud)

但是这个标准只返回volumeCodes(字符串列表).我需要得到一个Books 列表.所以我尝试使用变形金刚:

    Criteria c = s.createCriteria(Book.class);
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
    c.setResultTransformer(Transformers.aliasToBean(Book.class));
    List<Book> result = c.list();
Run Code Online (Sandbox Code Playgroud)

此代码返回空值列表.是否有可能用标准来做到这一点?

Ziu*_*iul 6

首先,projecton过滤检索的数据量,如果你想要更多的数据,你也应该将这些属性添加到投影中.

例:

c.setProjection( Projections.projectionList()
    .add( Projections.property("id").as("id") )
    .add( Projections.property("descripction").as("description") )
    .add( Projections.groupProperty("volumeCode").as("volumeCode") ));
Run Code Online (Sandbox Code Playgroud)

现在,转换器执行它所说的"Alias to Bean",它与java bean"Book.java"的属性进行别名匹配.

编辑:

如果没有变换器,如果投影具有多个属性,结果将如下所示:

for(Object[] item:criteria.list()){
    System.out.println( (String)item[0] ); //ID
    System.out.println( (String)item[1] ); //Description
    System.out.println( (String)item[2] ); //Volume code
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么你得到关于变换器的强制转换异常,尝试将每个别名与你的java bean的属性名匹配.


Jer*_*ome 5

cz_Nesh。抱歉我的第一个答案。我阅读了 Hibernate api 并阅读了一些我发现的 Hibernate 源代码。如果您使用此代码

session.createCriteria(EmpUserImpl.class).list();  
Run Code Online (Sandbox Code Playgroud)

它将返回列表 EmpUserImpl。如果您使用此代码

        criteria.setProjection(Projections.projectionList()
            .add(Projections.groupProperty("company").as("company"))
            .add(Projections.property("name").as("name"))
            .add(Projections.property("company").as("company")));
        List list = criteria.list();
Run Code Online (Sandbox Code Playgroud)

它会返回 List ,不是 List EmpUserImpl 为什么?我看到标准的父类 CriteriaSpecification 我发现。

public interface CriteriaSpecification {

/**
 * The alias that refers to the "root" entity of the criteria query.
 */
public static final String ROOT_ALIAS = "this";

/**
 * Each row of results is a <tt>Map</tt> from alias to entity instance
 */
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE;

/**
 * Each row of results is an instance of the root entity
 */
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE;

/**
 * Each row of results is a distinct instance of the root entity
 */
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE;

/**
 * This result transformer is selected implicitly by calling <tt>setProjection()</tt>
 */
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE;

/**
 * Specifies joining to an entity based on an inner join.
 *
 * @deprecated use {@link org.hibernate.sql.JoinType#INNER_JOIN}
 */
@Deprecated
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue();

/**
 * Specifies joining to an entity based on a full join.
 *
 * @deprecated use {@link org.hibernate.sql.JoinType#FULL_JOIN}
 */
@Deprecated
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue();

/**
 * Specifies joining to an entity based on a left outer join.
 *
 * @deprecated use {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}
 */
@Deprecated
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue();
Run Code Online (Sandbox Code Playgroud)

}

你能看到 public static final ResultTransformer PROJECTION 吗?它说这个结果转换器是通过调用 setProjection() 隐式选择的,这意味着当你使用 criteria.setProjection 时,结果不会列出 EmpUserImpl,因为 ResultTransformer 从“ROOT_ENTITY”更改为“PROJECTION”。它将通过 Projection 打包(如选择名称,oid ..)。所以,如果你想返回 List EmpUserImpl 你需要设置 Projections.property("name").as("name").,(如果你需要 name 就设置 name)。这是我的代码。

        Criteria criteria = session.createCriteria(EmpUserImpl.class);
    criteria.setProjection(Projections.projectionList()
            .add(Projections.groupProperty("company").as("company"))
            .add(Projections.property("name").as("name"))
            .add(Projections.property("company").as("company")));
    criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class));
    List<EmpUserImpl> list = criteria.list();
    for (EmpUserImpl empUserImpl : list) {
        System.out.println(empUserImpl.getName());
    }
Run Code Online (Sandbox Code Playgroud)

它可以工作。我希望它能帮助你。