1. SpringBoot2集成MyBatisPlus核心流程解析
作为Java开发者,当我们需要快速构建数据访问层时,MyBatisPlus(简称MP)绝对是提升开发效率的利器。它基于MyBatis进行了深度封装,在保留MyBatis灵活性的同时,提供了大量开箱即用的功能。下面我将结合自己多个项目的实战经验,详细拆解SpringBoot2项目集成MyBatisPlus的全流程。
1.1 环境准备与依赖配置
首先确保你的开发环境满足以下条件:
- JDK 1.8+
- Maven 3.0+
- SpringBoot 2.x版本
- 任意IDE(推荐IntelliJ IDEA)
在pom.xml中添加关键依赖时需要注意版本兼容性。根据我的经验,SpringBoot2.x项目建议使用MP 3.5.x版本:
xml复制<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.17</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
提示:实际项目中建议使用MySQL等生产级数据库,H2仅适合演示和测试环境
1.2 基础配置详解
application.yml的配置需要特别注意几个关键点:
yaml复制spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC
username: root
password: 123456
sql:
init:
mode: always # 启动时执行初始化脚本
schema-locations: classpath:db/schema.sql
data-locations: classpath:db/data.sql
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志
在启动类上添加@MapperScan注解时,我建议采用精确到mapper包路径的方式:
java复制@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2. 核心功能实现与最佳实践
2.1 实体类设计技巧
实体类设计是使用MP的基础,这里分享几个实用技巧:
java复制@Data
@TableName("sys_user") // 显式指定表名
public class User {
@TableId(type = IdType.AUTO) // 主键策略
private Long id;
@TableField("user_name") // 字段映射
private String username;
private Integer age;
@TableField(exist = false) // 非表字段
private String tempField;
@TableLogic // 逻辑删除标记
private Integer deleted;
}
经验:建议所有表字段都使用包装类型(Integer/Long等),避免基本类型带来的默认值问题
2.2 Mapper接口开发
MP的强大之处在于BaseMapper提供的通用方法:
java复制public interface UserMapper extends BaseMapper<User> {
// 自定义SQL方法
@Select("SELECT * FROM sys_user WHERE age > #{age}")
List<User> selectByAge(@Param("age") Integer age);
}
实测发现,当表字段较多时,使用@ResultMap注解可以显著提升映射效率:
java复制@Results(id = "userMap", value = {
@Result(property = "id", column = "id"),
@Result(property = "username", column = "user_name")
// 其他字段映射...
})
@Select("SELECT * FROM sys_user WHERE id = #{id}")
User selectByIdWithResultMap(Long id);
3. 高级特性实战应用
3.1 条件构造器深度使用
QueryWrapper是MP最强大的功能之一,分享几个复杂查询的写法:
java复制// 多条件查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("user_name", "张")
.between("age", 20, 30)
.isNotNull("email")
.orderByDesc("create_time");
// 嵌套查询
wrapper.nested(i -> i.eq("status", 1).or().eq("vip_level", 3));
// 动态SQL构建
public List<User> searchUsers(UserQuery query) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
if (StringUtils.isNotBlank(query.getKeyword())) {
wrapper.and(w -> w.like("user_name", query.getKeyword())
.or()
.like("email", query.getKeyword()));
}
if (query.getMinAge() != null) {
wrapper.ge("age", query.getMinAge());
}
return userMapper.selectList(wrapper);
}
3.2 分页插件配置与优化
分页是业务系统的刚需,MP的分页插件需要特别配置:
java复制@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setMaxLimit(500L); // 单页最大500条
paginationInnerInterceptor.setOverflow(true); // 超出总页数后回到第一页
interceptor.addInnerInterceptor(paginationInnerInterceptor);
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
使用分页时推荐创建专用DTO:
java复制public Page<User> queryUserPage(UserPageQuery query) {
Page<User> page = new Page<>(query.getCurrent(), query.getSize());
QueryWrapper<User> wrapper = new QueryWrapper<>();
// 构建查询条件...
return userMapper.selectPage(page, wrapper);
}
4. 生产环境问题排查指南
4.1 常见报错解决方案
问题1:启动时报找不到Mapper接口
解决方案:
- 检查@MapperScan路径是否正确
- 确保mapper接口有@Repository注解
- 在pom.xml中确认mybatis-plus-boot-starter依赖存在
问题2:字段值为null时未更新
解决方法:
yaml复制mybatis-plus:
global-config:
db-config:
logic-not-delete-value: 0 # 未删除值
logic-delete-value: 1 # 已删除值
insert-strategy: not_null # 插入策略
update-strategy: not_null # 更新策略
4.2 性能优化建议
- 批量操作优化:
java复制// 批量插入
List<User> userList = ...;
userMapper.insertBatchSomeColumn(userList);
// 批量更新
userMapper.updateBatchById(userList);
- SQL打印优化:
yaml复制mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# 配合logging.level配置使用
logging:
level:
com.example.demo.mapper: debug
- 二级缓存配置:
java复制@CacheNamespace
public interface UserMapper extends BaseMapper<User> {
// 方法实现...
}
5. 扩展功能集成方案
5.1 代码生成器实战
MP的代码生成器可以节省大量重复劳动:
java复制FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo", "root", "123456")
.globalConfig(builder -> {
builder.author("developer") // 设置作者
.outputDir(System.getProperty("user.dir") + "/src/main/java"); // 输出目录
})
.packageConfig(builder -> {
builder.parent("com.example.demo") // 父包名
.moduleName("system") // 模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper")); // xml路径
})
.strategyConfig(builder -> {
builder.addInclude("sys_user") // 表名
.entityBuilder()
.enableLombok()
.controllerBuilder()
.enableRestStyle();
})
.execute();
5.2 多数据源集成
对于复杂业务系统,多数据源是常见需求:
java复制@Configuration
@MapperScan(basePackages = "com.example.mapper.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class Db1DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.db1")
public DataSource db1DataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/db1/*.xml"));
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate db1SqlSessionTemplate(
@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
在实际项目中,我发现合理使用MyBatisPlus可以提升至少50%的数据层开发效率。特别是在快速迭代的业务场景下,它的条件构造器和通用CRUD方法能显著减少样板代码。不过也要注意,复杂SQL还是建议使用XML方式编写,保持可维护性。
