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