序言
springboot + mybatis-plus + druid 是如今非常好用一套组合方案,可以大大提升我们开发的效率。
本文记录一下老马自己的实战使用笔记,希望给你的工作和学习提供一点帮助。
springboot 整合 mybatis-plus
maven 依赖
- 版本
3.4.41.3.12.31.85.1.471.1.141.8.102.01.5.11.RELEASE
- 依赖
org.mybatis mybatis ${mybatis.version} org.mybatis mybatis-spring ${mybatis-spring.version} com.baomidou mybatis-plus ${mybatis-plus.version} mybatis org.mybatis mybatis-spring org.mybatis com.baomidou mybatis-plus-boot-starter ${mybatis-plus.version} org.apache.velocity velocity-engine-core ${velocity.version} mysql mysql-connector-java ${mysql.version} runtime com.alibaba druid-spring-boot-starter ${druid.version} org.springframework.boot spring-boot-starter-jdbc ${spring-boot.version} org.springframework.boot spring-boot-starter-test ${spring-boot.version} test org.springframework.boot spring-boot-starter-web ${spring-boot.version}
配置文件
server: port: 8080spring: datasource: druid: username: root password: 123456 url: jdbc:mysql://localhost:3306/padmin?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.jdbc.Drivermybatis-plus: mapper-locations: classpath*:com/github/houbb/privilege/admin/dal/mapper/*Mapper.xml type-aliases-package: com.github.houbb.privilege.admin.dal.entity
到这里,最基本的配置就完成了。
实现原理,就是通过 springboot-starter 实现的。
分页
如果我们希望使用分页插件,那么配置一下:
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@[email protected](basePackages = "com.github.houbb.privilege.admin.dal.mapper")public class DataSourceConfig { @Bean public PaginationInterceptor paginationInterceptor(){ PaginationInterceptor page = new PaginationInterceptor(); //设置方言类型 page.setDialectType("mysql"); return page; }}
分页测试
正常情况
public BasePageInfo pageQueryList(CommonPageReq pageReq) { Wrapper userWrapper = new EntityWrapper<>(); // 分页查询 Page userPage = new Page<>(pageReq.getPageNum(), pageReq.getPageSize()); userPage = this.selectPage(userPage, userWrapper); BasePageInfo pageInfo = new BasePageInfo<>(); pageInfo.setList(userPage.getRecords()); pageInfo.setTotal(userPage.getTotal()); return pageInfo;}
发现这种分页信息是正常的。
不生效的情况
import com.baomidou.mybatisplus.mapper.EntityWrapper;import com.baomidou.mybatisplus.mapper.Wrapper;import com.baomidou.mybatisplus.plugins.pagination.PageHelper;import com.github.houbb.heaven.util.lang.StringUtil;import com.github.houbb.privilege.admin.common.dto.BasePageInfo;import com.github.houbb.privilege.admin.common.dto.common.CommonPageReq;import com.github.houbb.privilege.admin.dal.entity.Role;import com.github.houbb.privilege.admin.dal.mapper.RoleMapper;import com.github.houbb.privilege.admin.service.service.RoleService;import com.baomidou.mybatisplus.service.impl.ServiceImpl;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class RoleServiceImpl extends ServiceImpl implements RoleService { @Override public BasePageInfo pageQueryList(CommonPageReq pageReq) { PageHelper.startPage(pageReq.getPageNum(), pageReq.getPageSize()); Wrapper roleWrapper = new EntityWrapper<>(); List userList = baseMapper.selectList(roleWrapper); long total = PageHelper.getTotal(); BasePageInfo pageInfo = new BasePageInfo<>(); pageInfo.setList(userList); pageInfo.setTotal(total); return pageInfo; }}
一开始以为是 PageHelper.startPage 后面不是紧跟查询方法,后来调整顺序发现也不行。
问题原因
然后 debug 了一下源码。
mybatis-plus 的 PaginationInterceptor 类
// 先判断是不是SELECT操作MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) { return invocation.proceed();}RowBounds rowBounds = (RowBounds) metaObject.getValue("delegate.rowBounds");/* 不需要分页的场合 */if (rowBounds == null || rowBounds == RowBounds.DEFAULT) { // 本地线程分页 if (localPage) { // 采用ThreadLocal变量处理的分页 rowBounds = PageHelper.getPagination(); if (rowBounds == null) { return invocation.proceed(); } } else { // 无需分页 return invocation.proceed(); }}
发现属性 localPage 没有启动,于是调整一下分页的配置:
@Beanpublic PaginationInterceptor paginationInterceptor(){ PaginationInterceptor page = new PaginationInterceptor(); //设置方言类型 page.setDialectType("mysql"); page.setLocalPage(true); return page;}
然后分页就正常了。
小结
myabtis-plus 个人使用的版本可能相对比较低,这种基于 ThreadLocal 的分页方式没有默认开启。
有时候去网上查也很难查到类似的问题。因为不同的版本,问题可能完全不同,所以还是需要看源码。
本实战系列用于记录 springboot 的实际使用和学习笔记。
希望本文对你有所帮助,如果喜欢,欢迎点赞收藏转发一波。
我是老马,期待与你的下次相遇。
拓展阅读
面试官:知道 springboot 的启动原理吗?
5 分钟入门 springboot 实战学习笔记
实现你的自定义 springboot starter 实战
springboot 整合阿里 druid 数据库连接池实战