SpringBoot集成MyBatis-Plus:分页、条件查询与SQL日志全攻略
2025.09.18 16:02浏览量:0简介:本文详细介绍SpringBoot项目中集成MyBatis-Plus的分页插件、条件构造器查询及SQL打印配置方法,通过代码示例和场景说明帮助开发者快速掌握核心功能。
SpringBoot集成MyBatis-Plus:分页、条件查询与SQL日志全攻略
一、MyBatis-Plus核心功能概述
MyBatis-Plus作为MyBatis的增强工具,在保持原生功能基础上提供了分页查询、条件构造器、SQL性能分析等核心能力。相比传统MyBatis开发,其代码量可减少40%以上,特别适合需要快速迭代的业务场景。
1.1 功能优势对比
功能模块 | 传统MyBatis实现 | MyBatis-Plus实现 | 效率提升 |
---|---|---|---|
分页查询 | 手动拼接SQL | 自动拦截器 | 85% |
条件查询 | 多条件if判断 | 链式API调用 | 70% |
SQL日志 | 日志框架配置 | 内置分析器 | 100% |
二、分页插件配置与使用
2.1 依赖配置
在pom.xml中添加核心依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
2.2 插件注册
创建配置类实现分页拦截:
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
2.3 分页查询实现
服务层实现示例:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public IPage<User> queryByPage(Long current, Long size) {
// 创建分页对象
Page<User> page = new Page<>(current, size);
// 执行分页查询
return userMapper.selectPage(page, null);
}
}
2.4 多数据源适配
针对不同数据库的分页SQL差异,插件支持自动适配:
// Oracle分页配置示例
@Bean
public MybatisPlusInterceptor oracleInterceptor() {
PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor(DbType.ORACLE);
interceptor.setMaxLimit(2000L); // 设置最大分页数
return new MybatisPlusInterceptor().addInnerInterceptor(interceptor);
}
三、条件查询构造器详解
3.1 基础条件查询
Wrapper接口体系包含:
QueryWrapper
:普通条件查询LambdaQueryWrapper
:Lambda表达式查询UpdateWrapper
:更新条件构造
// 查询年龄大于25且姓名包含"张"的用户
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 25)
.like(User::getName, "张");
List<User> users = userMapper.selectList(wrapper);
3.2 复杂条件组合
支持嵌套查询和逻辑运算:
// 查询(年龄<20或工资>5000)且部门为"研发部"的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.nested("age < 20 or salary > 5000")
.eq("dept", "研发部");
3.3 常用条件方法
方法名 | 说明 | 示例 |
---|---|---|
eq() | 等于 | wrapper.eq(“name”, “张三”) |
ne() | 不等于 | wrapper.ne(“status”, 0) |
between() | 区间范围 | wrapper.between(“age”, 20,30) |
in() | IN查询 | wrapper.in(“id”, ids) |
orderByAsc() | 升序排序 | wrapper.orderByAsc(“create_time”) |
四、SQL打印与性能分析
4.1 基础日志配置
在application.yml中配置:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4.2 性能分析插件
配置SQL执行分析器:
@Bean
public MybatisPlusInterceptor performanceInterceptor() {
return new MybatisPlusInterceptor().addInnerInterceptor(
new IllegalSQLInnerInterceptor() // 非法SQL拦截
.addSqlParserFilter(metaObject -> {
// 排除特定表
String tableName = metaObject.getTableInfo().getTableName();
return !"sys_log".equals(tableName);
})
);
}
4.3 P6Spy日志增强(推荐)
添加依赖:
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
修改配置:
spring:
datasource:
url: jdbc
mysql://localhost:3306/test
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
自定义spy.properties:
# 日志格式配置
logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)
五、高级应用场景
5.1 动态表名处理
实现TableNameHandler接口:
public class DynamicTableNameHandler implements TableNameHandler {
@Override
public String dynamicTableName(String sql, String tableName) {
// 根据分表策略返回实际表名
return tableName + "_" + (System.currentTimeMillis() % 4);
}
}
5.2 多租户SQL拦截
通过InnerInterceptor实现租户隔离:
@Bean
public MybatisPlusInterceptor tenantInterceptor() {
TenantLineInnerInterceptor interceptor = new TenantLineInnerInterceptor(
new TenantLineHandler() {
@Override
public Expression getTenantId() {
return new LongValue(1L); // 硬编码租户ID
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
}
);
return new MybatisPlusInterceptor().addInnerInterceptor(interceptor);
}
六、最佳实践建议
分页参数校验:
public IPage<User> safeQuery(Long current, Long size) {
if (current == null || current < 1) current = 1;
if (size == null || size > 100) size = 10; // 限制最大分页数
return userMapper.selectPage(new Page<>(current, size), null);
}
复杂查询优化:
- 避免在Wrapper中使用过多OR条件
- 大数据量分页使用
selectPage
的optimizeJoin
参数 - 定期清理分页插件的缓存
- SQL日志管理:
- 生产环境建议使用P6Spy而非StdOutImpl
- 设置合理的日志级别(建议WARN以上)
- 对敏感数据表进行脱敏处理
七、常见问题解决方案
7.1 分页总数不准确
问题原因:多表关联时COUNT(*)计算错误
解决方案:
// 自定义COUNT查询
Page<User> page = new Page<>(1, 10);
page.setOptimizeJoin(true); // 开启优化
IPage<User> result = userMapper.selectMapsPage(page, wrapper);
7.2 条件查询失效
典型场景:
// 错误示例:条件方法调用顺序错误
wrapper.orderByAsc("id").eq("status", 1); // orderBy会覆盖之前的条件
// 正确写法
wrapper.eq("status", 1).orderByAsc("id");
7.3 SQL日志不输出
排查步骤:
- 检查日志框架配置(Logback/Log4j2)
- 确认MyBatis日志级别设置为DEBUG
- 检查是否被其他拦截器覆盖
八、版本兼容性说明
MyBatis-Plus版本 | SpringBoot版本 | 适配说明 |
---|---|---|
3.5.x | 2.7.x | 推荐生产环境使用 |
3.4.x | 2.5.x | 长期支持版本 |
3.3.x | 2.3.x | 仅建议旧项目维护使用 |
注:使用SpringBoot 3.x需等待MyBatis-Plus 4.0正式发布
九、总结与展望
MyBatis-Plus通过分页插件、条件构造器和SQL分析三大核心功能,显著提升了CRUD操作的开发效率。在实际项目中,建议:
- 中小型项目可直接使用标准配置
- 大型分布式系统需结合动态表名和多租户功能
- 性能敏感场景应启用P6Spy进行深度优化
发表评论
登录后可评论,请前往 登录 或 注册