SpringBoot集成MyBatis-Plus分页插件

原文:SpringBoot集成MyBatis-Plus分页插件_木木与呆呆的技术博客_51CTO博客

1.说明
MyBatis使用分页查询功能,

需要配置分页插件,

如果没有配置,

则分页功能不生效。

2.分页查询API
下面列举了两个内置的分页查询API,

使用这些API时需要配置分页插件,

当然也可以自定义分页查询API:

com.baomidou.mybatisplus.extension.service.IService.page(E, Wrapper<T>) /**  * 翻页查询  *  * @param page         翻页对象  * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}  */ default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {     return getBaseMapper().selectPage(page, queryWrapper); }
1.
com.baomidou.mybatisplus.core.mapper.BaseMapper.selectPage(P, Wrapper<T>) /**  * 根据 entity 条件,查询全部记录(并翻页)  *  * @param page         分页查询条件(可以为 RowBounds.DEFAULT)  * @param queryWrapper 实体对象封装操作类(可以为 null)  */ <P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
1.
可以看到IService.page()实际使用的也是BaseMapper.selectPage()。

3.配置分页插件
新增配置类MybatisPlusConfig.java如下:

package com.yuwen.spring.demo.config;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;  import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;  @Configuration public class MybatisPlusConfig {     @Bean     public MybatisPlusInterceptor mybatisPlusInterceptor() {         // MyBatis Plus分页插件         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();         interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));         return interceptor;     } }
1.
另外旧版的配置如下,

用作配置参考:

@Bean public PaginationInterceptor paginationInterceptor() {     PaginationInterceptor paginationInterceptor = new PaginationInterceptor();     // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false     // paginationInterceptor.setOverflow(false);     // 设置最大单页限制数量,默认 500 条,-1 不受限制     // paginationInterceptor.setLimit(500);     // 开启 count 的 join 优化,只针对部分 left join     paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));     return paginationInterceptor; }
1.
4.使用分页查询
批量查询用户支持分页参数,

pageNum代表当前页数,

pageSize代表每页大小,

分页查询代码如下:

public List<UserEntity> queryBatchUser(Integer pageNum, Integer pageSize) {     if (pageNum == null) {         pageNum = 1;     }     if (pageSize == null) {         pageSize = Integer.MAX_VALUE;     }      IPage<UserEntity> page = new Page<UserEntity>();     page.setCurrent(pageNum);     page.setSize(pageSize);     // 返回的pageNew和page是同一个对象     IPage<UserEntity> pageNew = userService.page(page);     List<UserEntity> records = pageNew.getRecords();     return records; }
1.
5.分页查询结果
执行分页查询请求:

http://IP:Port/userProject/controller/user/batch?pageNum=2&pageSize=2
1.
输出查询日志如下,

发现后台执行了2条SQL,

第1条是查询用户总数,

第2条是真正的分页查询:

17:23:36.333 [http-nio-8088-exec-6] DEBUG [com.yuwen.spring.demo.aspect.WebLogAspect.around(WebLogAspect.java:34)] - UserControllerImpl.queryBatchUser(..) start, request=[null, 2, 2] 17:23:36.336 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==>  Preparing: SELECT COUNT(*) AS total FROM tbl_user 17:23:36.337 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==> Parameters:  17:23:36.341 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - <==      Total: 1 17:23:36.342 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==>  Preparing: SELECT id,`name`,email,birthday,create_time,update_time FROM tbl_user LIMIT ?,? 17:23:36.343 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==> Parameters: 2(Long), 2(Long) 17:23:36.348 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - <==      Total: 2 17:23:36.349 [http-nio-8088-exec-6] DEBUG [com.yuwen.spring.demo.aspect.WebLogAspect.around(WebLogAspect.java:46)] - UserControllerImpl.queryBatchUser(..) end, result=[UserEntity [id=1991, name=yuwen, email=yuwen3@asiainfo.com, birthday=1989-06-30, createTime=2021-11-25 11:22:26, updateTime=null], UserEntity [id=1992, name=yuwen, email=yuwen3@asiainfo.com, birthday=1989-06-30, createTime=2021-11-25 11:22:34, updateTime=null]]
1.
6.pageNum=0的情况
当设置pageNum为0时,

查询返回结果和pageNum为1时相同,

代码中对pageNum的处理如下:

com.baomidou.mybatisplus.core.metadata.IPage.offset()   /**  * 计算当前分页偏移量  */ default long offset() {     long current = getCurrent();     if (current <= 1L) {         return 0L;     }     return Math.max((current - 1) * getSize(), 0L); }
1.
可以看出,对应pageNum小于等于1时,

查询返回结果都是和pageNum=1相同,

所以这里建议pageNum从1开始,不要使用0及负数。

7.pageNum≥1的情况
实际测试中,

以MySQL为例,

pageNum为大于等于1的时候,

会影响分页查询的生成的SQL。

7.1.pageNum=1时的分页查询SQL
[org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==>  Preparing: SELECT id,`name`,email,birthday,create_time,update_time FROM tbl_user LIMIT ? 17:31:44.412 [http-nio-8088-exec-9] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==> Parameters: 2(Long)
1.
7.2.pageNum>1时的分页查询SQL
17:23:36.342 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==>  Preparing: SELECT id,`name`,email,birthday,create_time,update_time FROM tbl_user LIMIT ?,? 17:23:36.343 [http-nio-8088-exec-6] DEBUG [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:137)] - ==> Parameters: 2(Long), 2(Long)

7.3.代码解析
可以看到MySql分页实现的处理,

当offset为0时,即pageNum=1时,

对应不使用offset,

其他情况会使用offset,

可以和上面生成的SQL对应起来:

package com.baomidou.mybatisplus.extension.plugins.pagination.dialects; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.extension.plugins.pagination.DialectModel;  /**  * MYSQL 数据库分页语句组装实现  *  * @author hubin  * @since 2016-01-23  */ public class MySqlDialect implements IDialect {      @Override     public DialectModel buildPaginationSql(String originalSql, long offset, long limit) {         StringBuilder sql = new StringBuilder(originalSql).append(" LIMIT ").append(FIRST_MARK);         if (offset != 0L) {             sql.append(StringPool.COMMA).append(SECOND_MARK);             return new DialectModel(sql.toString(), offset, limit).setConsumerChain();         } else {             return new DialectModel(sql.toString(), limit).setConsumer(true);         }     } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值