spring data jpa Specification动态查询

由于最近研究jpa,使用我们的Specification来实现动态查询,但是出现一个非常糟糕的问题,也就是我们分页的时候出现第一页有数据,而第二页以后的页尾空白页。于是跟踪源码才得以明白。代码如下

1、controller

@RequestMapping(value = "/template")
@ResponseBody
public ModelAndView template(DataRequest request) {
   ModelAndView view = new ModelAndView();
   Integer count = new Long(service.count(request)).intValue();
   Page<PsUser> listpages = service.findAll(request);
   List<PsUser> content = listpages.getContent();
   view.addObject("count", count);
   view.addObject("datas",content);
   view.setViewName("psuser/template");
   return view;

2、service

@Override
public Page<PsUser> findAll(DataRequest request) {
   Pageable pageable = new PageRequest(request.getPageNo()/request.getPageSize(),request.getPageSize(), new Sort(new Order(Direction.ASC,"sorting")));
   int offset = pageable.getOffset();
   System.out.println(offset);
   Page<PsUser> page = psuserRepository.findAll(getCondition(request), pageable);
   return page;
}
private Specification<PsUser> getCondition(DataRequest request){
      Specification<PsUser> sp = new Specification<PsUser>() {
         /**
          * @param root root参数是我们用来对应实体的信息的。
          * @param query
          * @param cb criteriaBuilder可以帮助我们制作查询信息。
          * @return
          */
         @Override
         public Predicate toPredicate(Root<PsUser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            // 创建 Predicate
            Predicate predicate = cb.conjunction();
            // 组装条件
            if(TzStringUtils.isNotEmpty(request.getKeyword())){
               predicate.getExpressions().add(cb.like(root.<String>get("account")
                     ,"%"+ request.getKeyword() + "%"));
            }
            if(TzStringUtils.isNotEmpty(request.getKeyword())){
               predicate.getExpressions().add(cb.like(root.<String>get("name")
                     ,"%"+ request.getKeyword() + "%"));
            }
            return predicate;
         }

      };
      return sp;
   }

以上的跟正常的分页有所不同的地方就在于我们传入的Pageable是有所不同的,因为开始传入的new PageRequest(page,size,sort),但是这里将是传入的page仅仅是指的我们的第几页,而不是我们常规的页码,原因是findAll里面使用的pageable.getOffset()而不是pageable.getPage(),而Offset=page*size,我们传入了第二页为(page,size)  (10,10)就相当于多乘了一次pageSzie(),也就基本可能会大于我们的总记录数count(),源码如下:

org.springframework.data.jpa.repository.support.SimpleJpaRepository

protected <S extends T> Page<S> readPage(TypedQuery<S> query, Class<S> domainClass, Pageable pageable, Specification<S> spec) {
    query.setFirstResult(pageable.getOffset());
    query.setMaxResults(pageable.getPageSize());
    Long total = executeCountQuery(this.getCountQuery(spec, domainClass));
    List<S> content = total > (long)pageable.getOffset() ? query.getResultList() : Collections.emptyList();
    return new PageImpl(content, pageable, total);
}

org.springframework.data.domain.AbstractPageRequest

public int getOffset() {
    return this.page * this.size;
}

这样如果我们传入(page,size)如(10,10)这样的第二页,那是不是就会出现分页时第二页没有数据的情况。

学以之余,在此记录下一点点,希望对其他志同道合之人有所微末帮助。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值