我正在尝试使用 hibernate 和 displaytag 以及 Hibernate 进行查询结果分页 DetachedCriteria 物体会尽力阻挡。让我解释...

使用 displaytag 进行分页的最简单方法似乎是实现 PaginatedList 除其他外,该接口还具有以下方法:

/* Gets the total number of results. */
int getFullListSize();

/* Gets the current page of results. */
List getList();

/* Gets the page size. */
int getObjectsPerPage();

/* Gets the current page number. */
int getPageNumber();

/* Get the sorting column and direction */
String getSortCriterion();
SortOrderEnum getSortDirection();

我正在考虑将我的 PaginatedList 实现扔给 Criteria 对象,并让它按照这些思路工作......

getFullListSize() {
    criteria.setProjection(Projections.rowCount());
    return ((Long) criteria.uniqueResult()).intValue();
}

getList() {
    if (getSortDirection() == SortOrderEnum.ASCENDING) {
        criteria.addOrder(Order.asc(getSortCriterion());
    } else if (getSortDirection() == SortOrderEnum.DECENDING) {
        criteria.addOrder(Order.desc(getSortCriterion());
    }
    return criteria.list((getPageNumber() - 1) * getObjectsPerPage(),
                         getObjectsPerPage());
}

但这是行不通的,因为 addOrder() 或者 setProjection() 调用会修改标准对象,使其无法用于后续调用。我不完全确定调用的顺序,但是数据库会抛出错误 getFullListSize() 试图做一个“select count(*) ... order by ...“这显然是错误的。

我认为我可以通过创建自己的对象来跟踪查询条件并为每次调用重建 Criteria 对象来解决此问题,但这感觉就像重新发明另一个轮子。是否有更聪明的方法,可能复制最初传入的条件并处理该副本?

更新:看起来像 getList 首先被调用,并且 getFullListSize 之后会被多次调用,因此,一旦传入订单, getFullListSize 将失败。仅访问数据库一次是有意义的(在 getList 我想说)并缓存结果,无需复制/重置 Criteria 对象,但仍然...

更新(再次):忘记这个吧,一旦我完成了 count 我做不到 select, ,反之亦然。我真的需要两个不同的 Criteria 对象。

有帮助吗?

解决方案

很好,DetachedCriteria之后是序列化,所以你有内置的(如不雅)深克隆支持。你可以序列化的初始标准,一个byte []一次施工,那么你要使用它,每次反序列化。

其他提示

Criteria.setProjection(null);
Criteria.setResultTransformer(Criteria.ROOT_ENTITY);

将有效“复位”的标准本身根据rowCount投影和执行之间的标准。

我会确保你的订单还没有被添加做rowCount时之前,它会慢下来。我PaginatedList的实现寻找的结果之前,一定要先运行数查询,所以排序是不是一个问题。

http://weblogs.asp.net/stefansedich/archive/2008/10/03/paging-with-nhibernate-using-a-custom-extension-method-to-make-it-easier.aspx

在那篇文章中,我发现了 CriteriaTransformer.clone 方法。

那应该复制条件对象。

您还可以在 getlist 方法上设置投影。

糟糕,我没有注意到你指的是 java hibernate。无论如何,这个 http://forum.hibernate.org/viewtopic.php?t=939039

论坛帖子应该可以回答你的问题。

丑陋因为它可能是我结束了使用序列特技。在需要的时候我只是序列化DetachedCriteria对象上建设PaginatedList对象和一个字节数组反序列化。哎哟。

还有一件事值得尝试:

实现一个通用的DAO如在Hibernate的网站的一个建议,并把它传递给PaginatedList对象,沿着与限制对象。然后将PaginatedList对象会做类似

Criteria.forClass(myDAO.getPersistentClass())
        .add(myRestrictions)
        .addOrder(<someOrder>)

Criteria.forClass(myDAO.getPersistentClass())
        .add(myRestrictions)
        .setProjection(Projections.rowCount());

有没有尝试过呢,但它应该工作。

public static DetachedCriteria Clone(this DetachedCriteria criteria)
{
   var dummy = criteria.ToByteArray();
   return dummy.FromByteArray<DetachedCriteria>();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top