1. SpringBoot2与MyBatisPlus集成概述
在Java企业级开发中,数据持久层框架的选择直接影响开发效率和系统性能。MyBatis作为主流ORM框架之一,虽然灵活性强但需要编写大量样板代码。MyBatisPlus(简称MP)在MyBatis基础上进行了增强,提供了开箱即用的CRUD操作、条件构造器、分页插件等实用功能,能够显著减少重复代码量。
SpringBoot2作为目前仍广泛使用的稳定版本,与MyBatisPlus的集成组合特别适合需要快速迭代的中小型项目。这种组合的优势在于:
- 零XML配置:基于SpringBoot的自动配置特性
- 动态SQL生成:通过Lambda表达式构建类型安全的查询条件
- 丰富的扩展插件:如分页、乐观锁、多租户等企业级功能
- 与Spring生态无缝集成:兼容Spring事务管理等特性
2. 环境准备与基础配置
2.1 项目初始化
使用IDEA创建SpringBoot2项目时,建议选择以下配置:
- Spring Boot版本:2.7.x(长期支持版本)
- 打包方式:Maven/Gradle(本文以Maven为例)
- 依赖模块:Lombok(简化实体类)、Spring Web(可选)
关键pom.xml依赖配置:
xml复制<dependencies>
<!-- SpringBoot2基础starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.18</version>
</dependency>
<!-- MyBatisPlus核心依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 数据库驱动(以MySQL为例) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok注解处理器 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.2 数据库配置
application.yml典型配置示例:
yaml复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
sql:
init:
mode: always # 启动时执行初始化脚本
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志
global-config:
db-config:
id-type: auto # 主键生成策略
logic-delete-field: deleted # 逻辑删除字段名
logic-not-delete-value: 0 # 未删除值
logic-delete-value: 1 # 删除值
注意事项:生产环境务必关闭SQL日志输出,避免敏感信息泄露。测试阶段可以使用
StdOutImpl方便调试。
3. 核心功能实现
3.1 实体类与Mapper设计
实体类示例(使用Lombok简化代码):
java复制@Data
@TableName("sys_user") // 指定表名
public class User {
@TableId(type = IdType.AUTO) // 自增主键
private Long id;
@TableField("username") // 字段映射
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT) // 自动填充
private LocalDateTime createTime;
@TableLogic // 逻辑删除标记
private Integer deleted;
}
Mapper接口只需继承BaseMapper即可获得基础CRUD方法:
java复制@Repository // 可省略,Spring会自动注册
public interface UserMapper extends BaseMapper<User> {
// 自定义SQL方法
@Select("SELECT * FROM sys_user WHERE age > #{age}")
List<User> selectByAge(@Param("age") Integer age);
}
3.2 服务层实现
典型Service实现模式:
java复制@Service
@RequiredArgsConstructor // Lombok构造器注入
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
@Override
public Page<User> pageUsers(int current, int size, String name) {
return userMapper.selectPage(
new Page<>(current, size),
Wrappers.<User>lambdaQuery()
.like(StringUtils.isNotBlank(name), User::getName, name)
);
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean batchInsert(List<User> users) {
return SqlHelper.retBool(userMapper.insertBatchSomeColumn(users));
}
}
4. 高级特性集成
4.1 分页插件配置
MyBatisPlus的分页功能需要显式配置拦截器:
java复制@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
使用示例:
java复制// 分页查询
Page<User> page = new Page<>(1, 10);
userMapper.selectPage(page, Wrappers.emptyWrapper());
System.out.println("总记录数:" + page.getTotal());
4.2 代码生成器
自动化生成Entity/Mapper/Service代码:
java复制public class CodeGenerator {
public static void main(String[] args) {
AutoGenerator generator = new AutoGenerator();
// 数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig
.Builder("jdbc:mysql://localhost:3306/mp_demo", "root", "123456")
.build();
// 全局配置
GlobalConfig globalConfig = new GlobalConfig.Builder()
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.author("developer")
.openDir(false)
.build();
// 包配置
PackageConfig packageConfig = new PackageConfig.Builder()
.parent("com.example.mp")
.moduleName("demo")
.entity("entity")
.mapper("mapper")
.build();
generator.strategy(
new StrategyConfig.Builder()
.addInclude("sys_user") // 表名
.entityBuilder()
.enableLombok()
.logicDeleteColumnName("deleted")
.controllerBuilder()
.enableRestStyle()
.build()
);
generator.execute();
}
}
5. 常见问题排查
5.1 启动时报错找不到Mapper
典型错误:
code复制Field userMapper in com.example.service.impl.UserServiceImpl required a bean of type 'com.example.mapper.UserMapper' that could not be found.
解决方案:
- 确保启动类添加
@MapperScan注解:
java复制@SpringBootApplication
@MapperScan("com.example.mapper") // 指定Mapper接口所在包
public class Application {...}
- 检查Mapper接口是否添加了
@Repository注解(非必须但建议)
5.2 分页查询不生效
可能原因及解决:
- 未配置分页插件(见4.1节)
- 前端传参问题:确保pageNum/pageSize参数正确传递
- 自定义SQL未适配分页:
xml复制<!-- XML中需使用MP提供的分页参数 -->
<select id="selectByPage" resultType="User">
SELECT * FROM user ${ew.customSqlSegment}
</select>
5.3 逻辑删除失效
排查步骤:
- 确认全局配置中指定了逻辑删除字段(见2.2节)
- 实体类字段添加
@TableLogic注解 - 数据库表存在对应字段且类型匹配(建议使用tinyint)
6. 性能优化建议
6.1 批量操作优化
使用MP提供的批量插入方法:
java复制// 性能优于循环单条插入
userMapper.insertBatchSomeColumn(userList);
// 或者使用ExecutorType.BATCH模式
SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory()
.openSession(ExecutorType.BATCH);
UserMapper batchMapper = sqlSession.getMapper(UserMapper.class);
6.2 SQL监控与分析
配置慢SQL阈值:
yaml复制mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# 单位毫秒
slow-sql-millis: 1000
结合Druid监控:
java复制@Bean
public FilterRegistrationBean<StatFilter> statFilter() {
FilterRegistrationBean<StatFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new StatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("slowSqlMillis", "1000");
bean.addInitParameter("logSlowSql", "true");
return bean;
}
6.3 缓存策略选择
二级缓存配置示例:
yaml复制mybatis-plus:
configuration:
cache-enabled: true # 开启二级缓存
更推荐使用Spring Cache抽象:
java复制@CacheConfig(cacheNames = "user")
@Service
public class UserServiceImpl implements UserService {
@Cacheable(key = "#id")
public User getById(Long id) {
return userMapper.selectById(id);
}
@CacheEvict(allEntries = true)
public void clearCache() {}
}
在实际项目中,建议根据数据访问频率和一致性要求选择合适的缓存策略。对于高频读取、低频变更的数据,使用Redis作为缓存存储是常见方案
