为了账号安全,请及时绑定邮箱和手机立即绑定

利用Aspect对PageHelper的简单封装

标签:
Premiere

PageHelper是一个Mybatis插件,是一个非常方便使用的分页插件,常用方式为:PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
这种方式很方便,但这是非常容易出问题的使用方式。
作者在使用文档也有说明:

webp

image.png


其实实际使用中,尤其是业务复杂,查询条件很多的情况下,很容易造成疏忽,
然后出现莫名奇妙的分页,而且这种问题是很难定位的。
严谨的使用方式应该为:


try{
  PageHelper.startPage(1, 10);
  ...
  mapper.select();
}finally{
  PageHelper.clearPage();
}

保证PageHelper.clearPage()一定被调用。
但这样写起来非常啰嗦,这种模板类代码看起来很不优雅呢。
解决办法:使用Aop,消除模板代码。

定义注解:

@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface PagingQuery {    String pageNumParameterName() default "pageNum";//页号的参数名
    String pageSizeParameterName() default "pageSize";//每页行数的参数名}

定义切面:

@Aspect@Componentpublic class Aop{      @Around("@annotation(pagingQuery)")      public Object pagingQuery(ProceedingJoinPoint joinPoint, PagingQuery  pagingQuery) throws Throwable {
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();
          Class<?> returnType = signature.getMethod().getReturnType();          if (returnType == List.class) {
              String pageNumParameterName = pagingQuery.pageNumParameterName();
              String pageSizeParameterName = pagingQuery.pageSizeParameterName();              //获取request,从中获取分页参数
              ServletRequestAttributes currentRequestAttributes = (ServletRequestAttributes) RequestContextHolder
                    .currentRequestAttributes();
              HttpServletRequest request = currentRequestAttributes.getRequest();
              String pageNum = request.getParameter(pageNumParameterName);
              String pageSize = request.getParameter(pageSizeParameterName);              if (StringUtils.isNotBlank(pageNum) && StringUtils.isNotBlank(pageSize)) {                  try {
                      PageHelper.startPage(Integer.valueOf(pageNum), Integer.valueOf(pageSize));
                      Object result = joinPoint.proceed();                      return new PageInfo<>((List<?>) result);//建议自己实现返回类型,官方自带的返回数据太冗余了
                  } finally {//保证线程变量被清除
                      if (PageHelper.getLocalPage() != null)
                          PageHelper.clearPage();
                  }
              }
          }          return joinPoint.proceed();
      }
}

使用示例

在controller上使用:
    @PagingQuery(pageNumParameterName = "page", pageSizeParameterName = "size")//当前端调用时传的参数名跟默认不一致时需指定参数名
    @PostMapping("/list")    public List<User> list() {        return userService.findAll();
    }
或在service上使用:
@PagingQuerypublic List<User> pagingQuery(args) {
         ...        return mapper.select(condition);
    }

是不是更加方便优雅了。



作者:_mfeng
链接:https://www.jianshu.com/p/61334f4a45d2


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消