简体   繁体   English

Hibernate条件使用GROUP BY和RETURN ENTITY LIST

[英]Hibernate criteria Using GROUP BY and RETURN ENTITY LIST

I'm trying to use GROUP BY in my criteria. 我正在尝试在我的标准中使用GROUP BY I need to do this: 我需要这样做:

SELECT b FROM Book b GROUP BY volumeCode;

I have following code: 我有以下代码:

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

But this criteria returns only volumeCode s (a list of Strings). 但是此标准仅返回volumeCode (字符串列表)。 I need to get a list of Book s. 我需要获得Book的列表。 So I tried to use Transformers: 所以我尝试使用变形金刚:

    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();

This code returns list of null values. 此代码返回空值列表。 Is it possible to do that with criteria? 是否有可能用标准来做到这一点?

First of all, the projecton filters the amount of data retrieved, if you want more data, you should add those properties to the projection too. 首先,projecton过滤检索的数据量,如果你想要更多的数据,你也应该将这些属性添加到投影中。

Example: 例:

c.setProjection( Projections.projectionList()
    .add( Projections.property("id").as("id") )
    .add( Projections.property("descripction").as("description") )
    .add( Projections.groupProperty("volumeCode").as("volumeCode") ));

Now, the transformer does what it says "Alias to Bean", it does an alias match with the properties of your java bean "Book.java". 现在,转换器执行它所说的“Alias to Bean”,它与java bean“Book.java”的属性进行别名匹配。

Edit: 编辑:

Without the transformer, if the projection has more than one property, the result comes out like this: 如果没有变换器,如果投影具有多个属性,结果将如下所示:

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
}

Thats why you were getting the cast exception, about the transformer, try to match every alias with the property name of your java bean. 这就是为什么你得到关于变换器的强制转换异常的原因,试图将每个别名与你的java bean的属性名称相匹配。

cz_Nesh. cz_Nesh。 sorry about my first answer. 抱歉我的第一个答案。 i read Hibernate api and read some Hibernate source code i find that. 我读了Hibernate api并阅读了一些我发现的Hibernate源代码。 if you use this code 如果你使用这个代码

session.createCriteria(EmpUserImpl.class).list();  

it will return List EmpUserImpl. 它将返回List EmpUserImpl。 if you use this code 如果你使用这个代码

        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();

it will return List ,is not List EmpUserImpl why? 它会返回List,不是List EmpUserImpl为什么? i see the criterion's parent class CriteriaSpecification i find that . 我看到标准的父类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();

} }

can you see the public static final ResultTransformer PROJECTION ? 你能看到public static final ResultTransformer PROJECTION吗? it say that This result transformer is selected implicitly by calling setProjection() is mean when you use criteria.setProjection,the result will not List EmpUserImpl,because ResultTransformer is change to "PROJECTION" from "ROOT_ENTITY".it will packaging by Projection(like select name,oid .. ). 它说这个结果变换器是通过调用setProjection()隐式选择的,当你使用criteria.setProjection时,结果将不会列出EmpUserImpl,因为ResultTransformer从“ROOT_ENTITY”变为“PROJECTION”。它将按照Projection包装(如选择名称,oid ..)。 so, if you want to return List EmpUserImpl you need set Projections.property("name").as("name").,(if you need name just set name). 所以,如果你想返回List EmpUserImpl,你需要设置Projections.property(“name”)。as(“name”)。,(如果你需要名字只是设置名称)。 this is my code . 这是我的代码。

        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());
    }

it can work . 它可以工作。 i hope it can help you. 我希望它可以帮助你。

我想你可以使用: criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM