Hibernate投影列表

6
我需要从表中获取几个列的值。所以我使用了Projections来实现这一点。代码可以工作,但我认为它并不高效。
我的问题是当我使用ProjectionsList并将criteria.list设置为ArrayList时 - Bulletin对象为null。我不知道如何更好地解释这个问题。所以我将放置代码然后请您阅读下面的内容:
 List<Bulletin> list = new ArrayList<Bulletin>();
 BulletinList bulletinList = null;

 Criteria criteria = null;

 criteria = this.getSession().createCriteria(Bulletin.class)
            .setProjection(Projections.projectionList()
            .add(Projections.property(bulletinIdAttr))
            .add(Projections.property(docNameAttr))   
            .add(Projections.property(docTypeCodeAttr))
            );        
    criteria.addOrder(Order.desc(createdTimeAttr));

    List<Object> rows = criteria.list();
    for (Object r : rows) {
        Object[] row = (Object[]) r;
        Bulletin bull = new Bulletin();
        bull.setBulletinId((Long) row[0]);
        bull.setDocumentName((String) row[1]);
        bull.setDocumentTypeCode((String) row[2]);
        list.add(bull);
      }

    bulletinList = new BulletinList();
    bulletinList.setBulletins(list);

    return bulletinList;

我只需要将criteria.list设置为BulletinList(保存了一系列公告对象的类)。但是当我使用投影时,公告对象会变成null。

我也在阅读另一个帖子,建议使用

setResultTransformer(Transformers.aliasToBean

但这也不起作用。 所以,有人能帮助改进代码吗?
谢谢, 哈里什
3个回答

8
您可以使用

标签


 criteria = this.getSession().createCriteria(Bulletin.class)
            .setProjection(Projections.projectionList()
            .add(Projections.property(bulletinIdAttr),"bulletinIdAttr")
            .add(Projections.property(docNameAttr),"docNameAttr")   
            .add(Projections.property(docTypeCodeAttr),"docTypeCodeAttr")
            );        
criteria.addOrder(Order.desc(createdTimeAttr));
criteria.setResultTransformer(new AliasToBeanResultTransformer(Bulletin.class));
List<Bulletin> bulletinList = criteria.list();

这里的criteria.setResultTransformer(new AliasToBeanResultTransformer(Bulletin.class))会将你的结果转换为所需的POJO类,但请确保你的POJO类(在这种情况下是Bulletin.class)应该有适当的setter来设置属性的值。

现在,criteria.list()将返回Bulletin POJO类的列表,而不是Object。


不再参与那个项目了。但是非常感谢你的努力,尽管这是一个旧帖子。 - Harry
这个问题困扰了我很多天,我无法使用Projections.projectionList()获取所有属性细节,但现在我已经按照这种方式执行了我的项目,真的非常感谢@Shiva Agrawal先生。 - Vasantha Raj

5
  1. Projections.property() takes a String as an argument. In the code you provided the value of that String should be the name of a member of the Bulletin class. Presumably bulletinIdAttr, for example, is a String with such a value otherwise you would be getting runtime errors.
  2. When you call setProjection on a Criteria instance you are implicitly setting the ResultTransformer to PROJECTIONS and this is what you want. No need to call setResultTransformer yourself. I would simplify the routine a little like this

    List<Object[]> rows = criteria.list();
    for (Object[] row : rows) {
       Bulletin bull = new Bulletin();
       bull.setBulletinId((Long) row[0]);
       bull.setDocumentName((String) row[1]);
       bull.setDocumentTypeCode((String) row[2]);
       list.add(bull);
    }
    

但这不应该影响你的结果。你是否检查了rows是否为空?


非常感谢您的回复。正如我所说,我的代码可以按预期工作,但只是想知道它是否高效。是的,Projections.property()需要一个字符串作为参数。当我尝试使用您的代码块时,我遇到了这个错误: - Harry
类型不匹配:无法将元素类型Object转换为Object[],在for (Object[] row : rows)行上。我错过了什么?请告诉我。 - Harry
抱歉,Harish。我的原始答案格式不正确,这导致了行的声明错误。现在应该可以工作了。 - carbontax
这个很好用。非常感谢。但是你能告诉我使用List<Object[]>和List<Object>的区别以及为什么这样做更好吗? - Harry
1
一旦编译完成,这可能并没有太大的区别。但是,当您将结果集一次转换为Object而不是两次(一次作为Object,然后每行一次作为Object [])时,代码会更清晰。 - carbontax

3

如果您想从相同的条件进行第二次搜索,您需要更改或删除投影。例如,如果您首先搜索计数:

criteria.setProjection(Projections.rowCount());
Integer count = criteria.list().get(0);

然后想要获取所有对象:

criteria.setProjection(null);
List<Object> returnedObjects = criteria.list();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接