PageHelper是一個Mybatis插件捕仔,是一個非常方便使用的分頁插件幌墓,常用方式為:PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
這種方式很方便熊杨,但這是非常容易出問題的使用方式榕暇。
作者在使用文檔也有說明:
image.png
其實實際使用中,尤其是業(yè)務(wù)復(fù)雜,查詢條件很多的情況下悟衩,很容易造成疏忽,
然后出現(xiàn)莫名奇妙的分頁栓拜,而且這種問題是很難定位的座泳。
嚴謹?shù)氖褂梅绞綉?yīng)該為:
try{
PageHelper.startPage(1, 10);
...
mapper.select();
}finally{
PageHelper.clearPage();
}
保證PageHelper.clearPage()一定被調(diào)用。
但這樣寫起來非常啰嗦幕与,這種模板類代碼看起來很不優(yōu)雅呢挑势。
解決辦法:使用Aop,消除模板代碼啦鸣。
定義注解:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PagingQuery {
String pageNumParameterName() default "pageNum";//頁號的參數(shù)名
String pageSizeParameterName() default "pageSize";//每頁行數(shù)的參數(shù)名
}
定義切面:
@Aspect
@Component
public 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潮饱,從中獲取分頁參數(shù)
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);//建議自己實現(xiàn)返回類型,官方自帶的返回數(shù)據(jù)太冗余了
} finally {//保證線程變量被清除
if (PageHelper.getLocalPage() != null)
PageHelper.clearPage();
}
}
}
return joinPoint.proceed();
}
}
使用示例
在controller上使用:
@PagingQuery(pageNumParameterName = "page", pageSizeParameterName = "size")//當前端調(diào)用時傳的參數(shù)名跟默認不一致時需指定參數(shù)名
@PostMapping("/list")
public List<User> list() {
return userService.findAll();
}
或在service上使用:
@PagingQuery
public List<User> pagingQuery(args) {
...
return mapper.select(condition);
}
是不是更加方便優(yōu)雅了诫给。