前言:分页注解实现基于PageHelper,不过注解使用仅仅局限于小数据量的单机系统,如果大数据量或分布式系统或分表分库的,那么使用PageHelper绝对是让你死的很惨,废话不多说,开始上代码。
1.定义注解:Pagination.java
import java.lang.annotation.*;
/**
* 创建于 2019-07-22 17:53
*
* @author jiangyun
* @类说明:分页注解
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Pagination {
/**
* 是否支持分页
* @return
*/
boolean enable() default true;
/**
* 默认分页参数
* @return
*/
int pageNum() default 1;
/**
* 默认每页条数
* @return
*/
int pageSize() default 10;
}
2.对注解功能的实现:PaginationComponent.java
import com.github.pagehelper.PageHelper;
import com.yuntu.taoke.organization.annotation.Pagination;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
/**
* 创建于 2019-07-22 17:56
*
* @author jiangyun
* @类说明:支持分页插件组件
*/
@Aspect
@Slf4j
@Component
public class PaginationComponent {
/**
* 切入点
*/
@Pointcut("@annotation(com.yuntu.taoke.organization.annotation.Pagination)")//记得换成自己定义注解所在的包
public void startPage() {
log.info("start pagination...");
}
/**
* 前置通知处理
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around(value = "startPage()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
if (request == null) {
log.error("pagination only run on controller method");
} else {
if (!request.getMethod().equals("GET")) {
log.error("pagination only surpport get method");
} else {
Pagination pagination = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(Pagination.class);
if (pagination == null) {
log.error("pagination is null");
}
HashMap<String, Object> argsMap = convertArgsToMap(joinPoint);
if (pagination != null) {
if (pagination.enable()) {
Integer pageNum = argsMap.get("pageNum") == null || (Integer) argsMap.get("pageNum") < 1 ? pagination.pageNum() : (Integer) argsMap.get("pageNum");
Integer pageSize = argsMap.get("pageSize") == null || (Integer) argsMap.get("pageSize") < 1 ? pagination.pageSize() : (Integer) argsMap.get("pageSize");
PageHelper.startPage(pageNum, pageSize);
}
}
}
}
return joinPoint.proceed();
}
/**
* 将key和参数对应的值转成HashMap
* @param joinPoint
* @return
*/
private static HashMap<String, Object> convertArgsToMap(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();//获取
HashMap<String, Object> argsMap = new HashMap<>();
Signature signature = joinPoint.getSignature();//此处joinPoint的实现类是MethodInvocationProceedingJoinPoint
MethodSignature methodSignature = (MethodSignature) signature;//获取参数名
for (int i = 0; i < methodSignature.getParameterNames().length; i++) {
if (args[i] == null) continue;//屏蔽参数值为null的对象
argsMap.put(methodSignature.getParameterNames()[i], args[i]);
}
return argsMap;
}
}
3.使用方式:
好了,到此结束,如果您有什么更好的方式,欢迎交流,也欢迎指出博客中的不足或bug。