使用 Hibernate 的 Criteria api 进行排序和分页有一个很大的限制,它需要从数据库中检索不同的结果。api 提供的工具(如 DistinctRootTransformer)将不起作用,因为它是在从 db 检索实体后应用的,因此会中断分页和排序。获得具有关联限制的查询的不同结果的唯一方法是通过DetachedCriteria限制结果集:
DetachedCriteria dc = DetachedCriteria.forClass(Household.class, "h")
.createAlias("cats", "c", JoinType.LEFT_OUTER_JOIN)
.add(Restrictions.or(
Restrictions.isEmpty("cats"),
Restrictions.ne("c.name", "Sylvester")
))
.setProjection(Projections.distinct(Projections.property("h.id")));
Criteria criteria = session.createCriteria(Household.class)
.add(Property.forName("id").in(dc));
...apply paging, sorting and filtering to criteria.
有谁知道更好的方法,例如省略子查询并使用连接而不破坏分页?我的目标是找到一个可重用的解决方案,比如只将一个标准传递给另一个应用分页、排序和过滤的方法。
更新:
以下代码不起作用。由于加入,我必须使用 Resulttransformer,以获得不同的结果。但是,它是在排序和分页之后应用的。
Criteria criteria = session.createCriteria(Household.class)
.createAlias("cats", "c", JoinType.LEFT_OUTER_JOIN)
.add(Restrictions.ne("c.name","Sylvester"))
.setFirstResult((page - 1) * pagesize)
.setMaxResults(pagesize)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
例如,调试 sql 数据库将返回类似的内容:
home_id=1,...cat_ids={1,2};household_id=1,...cat_ids={1,2};household_id=2,...cat_ids={1};
在此示例中,将 pagesize 设置为 1 并查看页面 2 应该返回 uid 2,因为只有两个不同的用户。但正如您在数据库输出中看到的那样,它返回错误的 uid 1,因为 Resulttransformers 之后会启动。