hibernate 使用GROUP BY和RETURN ENTITY LIST

ctehm74n  于 2023-10-23  发布在  其他
关注(0)|答案(3)|浏览(127)

我试着在我的标准中使用GROUP BY。我需要这样做:

SELECT b FROM Book b GROUP BY volumeCode;

我有以下代码:

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

但是这个条件只返回volumeCode s(字符串列表)。我需要一份Book的列表。所以我试着用变形金刚:

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

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

3phpmpom

3phpmpom1#

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

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

现在,Transformer完成了它所说的“将数据转换为Bean”,它与Java Bean的属性“Book.java“进行别名匹配。
编辑:
如果没有Transformer,如果投影具有多个属性,则结果如下所示:

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
}

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

pxiryf3j

pxiryf3j2#

cz_Nesh.对不起我的第一个答案。我读了Hibernate的API,读了一些Hibernate的源代码,我发现。如果使用此代码,

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

它将返回List 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();

它会返回List,不是List EmpUserImpl为什么?我看到了criterion的父类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();

}
你能看到公共静态最终ResultTransformer PROJECTION吗?它说这个结果Transformer是通过调用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());
    }

它能起作用。希望对您有所帮助。

iq0todco

iq0todco3#

我想你可以用途:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

相关问题