??????@Bean ???public PaginationInterceptor paginationInterceptor(){ ???????PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); ???????// 开启 count 的 join 优化,只针对部分 left join ???????paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); ???????return paginationInterceptor; ???}
1. 分页实现的原理 Mybatis-plus分页插件使用的是IPage进行分页。IPage内部原理是基于拦截器,拦截的是方法以及方法中的参数。判断是否是查询操作,如果是查询操作,才会进入分页的处理逻辑。 进入分页逻辑处理后,拦截器会通过反射获取该方法的参数进行判断是否存在IPage对象的实现类。如果不存在则不进行分页,存在则将该参数赋值给IPage对象,然后进行拼接sql的处理完成分页操作。
???二、统一结果集 1. 创建返回码定义类public class ResultCode { ???????public final static int OK = 20000; ???????public final static int ERROR = 20001; ???????public final static int LOGIN_ERROR = 20002; ???????public final static int ACCESS_ERROR = 20003; ???????public final static int REMOTE_ERROR = 20004; ???????public final static int REPEAT_ERROR = 20005;}
2. 创建结果集类 @Data@ApiModel(value = "全局统一返回结果")public class R implements Serializable { ???public final static String OK_MSG = "请求成功"; ???public final static String FAIL_MSG = "请求失败"; ???@ApiModelProperty(value = "是否成功") ???private boolean success; ???@ApiModelProperty(value = "返回码") ???private Integer code; ???@ApiModelProperty(value = "返回消息") ???private String message; ???@ApiModelProperty(value = "返回数据") ???private Object data; ???@ApiModelProperty(value = "总条数") ???private Long total; ???@ApiModelProperty(value = "分页信息") ???private PageInfo pageInfo; ???@Data ???public static class PageInfo { ???????@ApiModelProperty("当前页") ???????protected int currentPage; ???????@ApiModelProperty("页大小") ???????protected int pageSize; ???????@ApiModelProperty("总记录数") ???????protected long totalCount; ???????@ApiModelProperty("总页数") ???????protected long totalPage; ???????public PageInfo() { ???????} ???????@ConstructorProperties({"currentPage", "pageSize", "totalCount", "totalPage"}) ???????public PageInfo(int currentPage, int pageSize, long totalCount, long totalPage) { ???????????this.currentPage = currentPage; ???????????this.pageSize = pageSize; ???????????this.totalCount = totalCount; ???????????this.totalPage = totalPage; ???????} ???} ???private R(){} ???private R(int code, String msg, Object data) { ???????this.code = code; ???????this.message = msg; ???????if (data instanceof Page<?>) { ???????????Page<?> page = (Page<?>) data; ???????????this.total = page.getTotal(); ???????????this.data = page.getRecords(); ???????????this.pageInfo = new PageInfo((int)page.getCurrent(), (int)page.getSize(), page.getTotal(), page.getPages()); ???????} else { ???????????this.data = data; ???????} ???} ???public static R ok(){ ???????R r = new R(); ???????r.setSuccess(true); ???????r.setCode(ResultCode.OK); ???????r.setMessage("成功"); ???????return r; ???} ???public static R ok(Object data) { ???????return new R(ResultCode.OK, OK_MSG, data); ???} ???public static R ok(String msg, Object data) { ???????return new R(ResultCode.OK, msg, data); ???} ???public static R error(){ ???????R r = new R(); ???????r.setSuccess(false); ???????r.setCode(ResultCode.ERROR); ???????r.setMessage("失败"); ???????return r; ???} ???public static R error(String msg) { ???????return new R(ResultCode.ERROR, msg, null); ???} ???public static R error(int errorCode, String msg) { ???????return new R(errorCode, msg, null); ???} ???public R message(String message){ ???????this.setMessage(message); ???????return this; ???} ???public R code(Integer code){ ???????this.setCode(code); ???????return this; ???} ???public R data(Object data){ ???????this.setData(data); ???????return this; ???}}
三、编写分页接口 1. 先编写查询类 代码如下:
@Datapublic class MemberQueryVo extends basePageEntity{ ???@ApiModelProperty(value = "用户名") ???private String userName;}
2. service层 先定义一个查询分页的接口,在实现类里做相关处理
@Servicepublic class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService { ???@Override ???public IPage<Member> listMemberPage(MemberQueryVo queryVo) { ???????IPage<Member> page = new Page<>(queryVo.getCurrentPage(),queryVo.getCurrentPage()); ???????//条件查询 ???????LambdaQueryWrapper<Member> queryWrapper = new LambdaQueryWrapper<Member>(); ???????if (StringUtils.isNotBlank(queryVo.getUserName())) { ???????????queryWrapper.like(Member::getUserName, queryVo.getUserName()); ???????} ???????return baseMapper.selectPage(page,queryWrapper); ???}}
3. controller层 编写分页接口,代码如下:
???@ApiOperation(value = "分页用户列表") ???@GetMapping(value = "/getPage") ???public R listPage(MemberQueryVo queryVo){ ???????IPage<Member> page = memberService.listMemberPage(queryVo); ???????return R.ok(page); ???}
4. 接口测试 直接通过swagger生成的api接口页面进行测试,当前页、每页参数传1时,返回的分页信息里,总数是两条,只返回了一条数据。说明分页成功。
???
在进行条件查询的时候,也成功查询对应数据。
感谢大家的阅读,上就是今天要讲的内容,本文简单介绍了如何配置分页插件、以及分页的原理。如有不足之处,纯属能力有限,还请多多包涵。