DetachedCriteria 分页Projection取消聚合条件 (解决方案)

当我们在使用DetachedCriteria进行分页查询时,需要对DetachedCriteria对象设置setProjection(Projections.rowCount()。可此时我们还需要DetachedCriteria对象去查询分页的结果集,而DetachedCriteria给的方法没有像 removeProjection()这样的条件。。而我也不想去拷贝一个DetachedCriteria对象,就对hibernate中DetachedCriteria类的源代码进行一番探究。。可以在github上下载到。我下载的4.1版本的,所以以下实例都源于4.1版本,其他版本请自行探究。

首先找到DetachedCriteria.java文件.

public class DetachedCriteria implements CriteriaSpecification, Serializable {

    private final CriteriaImpl impl;
    private final Criteria criteria;
    //下面代码先不看
}

DetachedCriteria 有两个属性,一个是Criteria 接口,另一个是Criteria 的实现类.

然后去找setProjection方法

public DetachedCriteria setProjection(Projection projection) {
        criteria.setProjection(projection);
        return this;
    }

这里说明Criteria这个接口类有setProjection抽象方法,因此,我们可以去CriteriaImpl这个实现类中去寻找setProjection的实现。

寻找CriteriaImpl.java文件,再搜寻setProjection函数

public Criteria setProjection(Projection projection) {
        this.projection = projection;
        this.projectionCriteria = this;
        setResultTransformer( PROJECTION );
        return this;
    }

上面这段代码是CriteriaImpl类中setProjection的实现.
总共三部操作。我们一步一步分析。

this.projection = projection;

我们先看下CriteriaImpl类中的私有变量

public class CriteriaImpl implements Criteria, Serializable {

    private final String entityOrClassName;
    private transient SessionImplementor session;
    private final String rootAlias;

    private List criterionEntries = new ArrayList();
    private List orderEntries = new ArrayList();
    private Projection projection;
    private Criteria projectionCriteria;

    private List subcriteriaList = new ArrayList();

    private Map fetchModes = new HashMap();
    private Map lockModes = new HashMap();

    private Integer maxResults;
    private Integer firstResult;
    private Integer timeout;
    private Integer fetchSize;

    private boolean cacheable;
    private String cacheRegion;
    private String comment;

    private FlushMode flushMode;
    private CacheMode cacheMode;
    private FlushMode sessionFlushMode;
    private CacheMode sessionCacheMode;

    private Boolean readOnly;

    private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;
}

可以发现projection变量原本是空值,所以我们复原时只要把projection=null就行

分析下一步:
this.projectionCriteria = this;
这个语句是为了返回 带有projection对象的Criteria实现类 而设置的
下列函数可证明

public Criteria getProjectionCriteria() {
        return projectionCriteria;
    }

因为没有public的 setProjectionCriteria 方法,我们不能设置为空,不过这不要紧。

**

看第三步(重中之中):

**
setResultTransformer( PROJECTION );

这里调用自身CriteriaImpl类中的方法,传了一个ResultTransformer类型的对象进去。

public Criteria setResultTransformer(ResultTransformer tupleMapper) {
        this.resultTransformer = tupleMapper;
        return this;
    }

可以看出也是简单的对resultTransformer 变量赋值。
此时,我们回头看resultTransformer 的默认值。

private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;

soga,所以,我们只要把值还原一下就行。

**

总结

**

如果你调用DetachedCriteria 中 detachedCriteria.setProjection(Projections.rowCount());
后还想需要detachedCriteria去查询结果集。。你只需要两步还原。

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

经实验,是有效滴。。

对Criteria中枚举变量(Criteria.ROOT_ENTITY……)有兴趣的可以去翻阅资料,,,因为我也还没搞太清楚。。有了解过的朋友可以传授一下。。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值