SpringBoot使用注解进行分页的实现示例
作者:JavaGaga 发布时间:2021-08-21 22:45:32
标签:SpringBoot,注解,分页
分页使用可以说非常普遍了,有时候会需要非常灵活的方式去开启或关闭分页,尝试使用一 * 解的方式来进行分页。
依赖安装
需要使用的依赖:
Mybatis-Plus
PageHelper
SpringBoot AOP
添加pom依赖
<!-- Mybatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<!-- 分页 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- AOP -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.5.5</version>
</dependency>
添加公共返回实体类
需要两种实体类,一种是不分页直接返回数据的,另一种是分页返回数据和总数据条数的
普通实体类 AjaxResult
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AjaxResult<T> {
public static final int CODE_SUCCESS = 200;
public static final int CODE_UNAUTHORIZED = 401;
public static final int CODE_FORBIDDEN = 403;
public static final int CODE_ERROR = 500;
public static final String MSG_SUCCESS = "操作成功";
public static final String MSG_FAILED = "操作失败";
public static final String MSG_NOT_PERMISSION = "用户权限不足";
public static final String MSG_UNAUTHORIZED = "用户未登录或身份已过期";
private int code;
private String msg;
private T data;
public static <T> AjaxResult success(int code, T data) {
return new AjaxResult(code, MSG_SUCCESS, data);
}
public static <T> AjaxResult success(T data) {
return success(CODE_SUCCESS, data);
}
public static AjaxResult success() {
return success(CODE_SUCCESS, null);
}
public static AjaxResult error(int code, String msg) {
return new AjaxResult(code, msg, null);
}
public static AjaxResult error(String msg) {
return error(CODE_ERROR, msg);
}
public static AjaxResult error() {
return new AjaxResult(CODE_ERROR, MSG_FAILED, null);
}
}
分页实体类 PageResult
继承AjaxResult,额外添加total、pageNo和pageSize等字段
@Data
public class PageResult extends AjaxResult {
private long total;
private long pageNo;
private long pageSize;
public PageResult() {
this.setCode(CODE_SUCCESS);
this.setMsg(MSG_SUCCESS);
}
public PageResult(AjaxResult ajaxResult) {
this();
if (Objects.nonNull(ajaxResult)) {
setCode(ajaxResult.getCode());
setMsg(ajaxResult.getMsg());
}
}
}
注解处理
分页注解 Pagination
创建一个用于分页的注解Pagination
其实这里的pageNo和pageSize没什么需求的话可以去掉的
/**
* 分页注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pagination {
// 第几页的请求参数名称 通过获取参数名称获取真正的pageNo
String pageNo() default "pageNo";
// 分页大小的请求参数名称
String pageSize() default "pageSize";
}
使用AOP进行分页
创建一个类用于处理分页注解,切入点要根据自己注解进行修改
@Aspect
@Component
@Slf4j
public class PaginationAspect {
/**
* 定义切入点
*/
@Pointcut("@annotation(cn.montaro.social.aspect.annotation.Pagination)")
public void access() {
}
@SneakyThrows
@Around("access()")
public Object around(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Pagination pagination = getPaginationAnnotation(joinPoint);
startPage(pagination.pageNo(), pagination.pageSize());
// 调用原本方法的内容并获取返回值
Object result = joinPoint.proceed(args);
// 返回的数据类型要保证和注解方法上的一致
return pageResult(result);
}
/**
* 获取Pagination注解
*
* @param joinPoint
* @return
*/
public Pagination getPaginationAnnotation(ProceedingJoinPoint joinPoint) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
Pagination pagination = method.getAnnotation(Pagination.class);
return pagination;
}
/**
* 开始分页
*/
private void startPage(String pageNoParameterName, String pageSizeParameterName) {
// 获取pageNo和pageSize
int pageNo = ServletUtils.getParameterToInt(pageNoParameterName, 1);
int pageSize = ServletUtils.getParameterToInt(pageSizeParameterName, 10);
PageHelper.startPage(pageNo, pageSize);
}
/**
* 对分页结果进行包装 如果分页成功则会返回PageResult
*
* @param result
*/
private Object pageResult(Object result) {
/**
* 如果分页成功,则查询返回的结应该是一个Page {@link com.github.pagehelper.Page}
* 进行一次强制转换就能获取到 total、pageNo、pageSize 这些字段
*/
PageInfo pageInfo = null;
AjaxResult ajaxResult = null;
// 列表数据 如果方法返回Page则直接使用 如果是AjaxResult则getData再封装
Object list = null;
if (result instanceof Page) {
list = result;
Page page = (Page) result;
pageInfo = new PageInfo(page);
} else if (result instanceof AjaxResult) {
ajaxResult = (AjaxResult) result;
Object data = ajaxResult.getData();
if (data instanceof List) {
list = data;
pageInfo = new PageInfo((List) data);
}
}
if (pageInfo != null) {
PageResult pageResult = new PageResult(ajaxResult);
pageResult.setData(list);
pageResult.setPageNo(pageInfo.getPageNum());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setTotal(pageInfo.getTotal());
return pageResult;
}
return result;
}
}
还有注解中使用到的ServletUtils
public class ServletUtils {
public static HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes = getRequestAttributes();
return requestAttributes.getRequest();
}
public static ServletRequestAttributes getRequestAttributes() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) requestAttributes;
}
public static Integer getParameterToInt(String parameterName, Integer defaultValue) {
HttpServletRequest request = getRequest();
String strValue = request.getParameter(parameterName);
Integer intValue = Convert.toInt(strValue, defaultValue);
return intValue;
}
public static Integer getParameterToInt(String parameterName) {
return getParameterToInt(parameterName, null);
}
}
使用注解
为了避免跑题,此处就省略mybatis-plus的使用了。
需要分页就加上@Pagination注解就行了,不需要就注释掉,代码完全不需要修改
分页的时候传入pageNo和pageSize参数就可以了,如果参数名需要更改,就修改@Pagination就可以了
编写Controller类
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
/**
* 列出所有用户
* @return
*/
@Pagination
@GetMapping("/list")
public AjaxResult list(UserQueryReq query) {
List<User> userList = userService.selectUserListByQuery(query);
return AjaxResult.success(userList);
}
}
测试
使用的Postman测试查看效果
使用注解的时候
把注解注释掉
来源:https://juejin.cn/post/7079661639078936589


猜你喜欢
- Java是垃圾回收语言的一种,其优点是开发者无需特意管理内存分配,降低了应用由于局部故障(segmentation fault)导致崩溃,同
- 序列化与反序列化序列化:把对象转换成字节的过程,称为对象序列化反序列化:把字节恢复成对象的过程,称为反序列化对象的持久化概念:把字节保存的硬
- 前言ps命令的作用是显示进程信息的。|符号,是个管道符号,表示左右两边两个命令同时执行。grep命令是查找(Global Regular E
- 今天碰到个很恶心的东西。。就是明明导入了相应的依赖文件(css,html,js等文件),路径也正确。。就是访问不了。。。。弄了一个多小时。。
- 引言今天给大家介绍一个非常有意思类库,基于java实现的简繁体转换,适用于后端、android等开发领域源码地址:* liuyueyi/qu
- 如何创建可以存放各种类型的数组?根据JavaSE的语法知识储备,如果现在让你们创建如标题一样的数组,你会怎么创建呢?答案是:使用 Objec
- 栈栈(stack)又名堆栈,它是一种运算受限的线性表 。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。
- 本文实例为大家分享了java实现飞机游戏的具体代码,供大家参考,具体内容如下MyGameFrame类:主要的调用类package sc.wh
- 下面我们就字符串连接方面分析。1.String打开String的源码,如图所示会发现存储字符串的字符数值是final常量。再看String的
- 目标依赖<!-- poi工具类--> <dependency>
- 本文实例讲述了Android编程开发之NotiFication用法。分享给大家供大家参考,具体如下:notification就是通知的意思,
- 1.object:匿名内部类在Android最常用的匿名内部类之一就是点击事件,用Java语言写的话就是下面这样:public interf
- 通过之前三篇关于Spring Boot异步任务实现的博文,我们分别学会了用@Async创建异步任务、为异步任务配置线程池、使用多个线程池隔离
- 本文实例为大家分享了Android仿抖音列表效果的具体代码,供大家参考,具体内容如下当下抖音非常火热,是不是也很心动做一个类似的app吗?那
- 设计模式通常分为三个主要类别:创建型模式结构型模式行为型模式。这些模式是用于解决常见的对象导向设计问题的最佳实践。以下是23种常见的设计模式
- Druid动态数据源配置 主要是继承AbstractRoutingDataSource再通过AOP来实现动态数据源切换.下面给大家介绍Dru
- 前言Lifecycle是Jetpack架构组件中用来感知生命周期的组件,使用Lifecycles可以帮助我们写出和生命周期相关更简洁更易维护
- Grpc是googe开发的,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。新公司的项目服务之间的调用使用的Grpc来实现服务间
- 本文实例讲述了Java日期操作类常见用法。分享给大家供大家参考,具体如下:一 取出当前日期时间1 代码import java.time.*;
- 1.与过滤器filter的区别2.springMVC中 * 的必须实现的三个方法:3. * 类的编写:package com.imooc.