Spring Boot集成MyBatis-Plus:高效持久层开发全攻略

一、环境搭建与基础配置

1.1 依赖管理方案

在Spring Boot项目中集成MyBatis-Plus需配置三个核心依赖:

  1. <dependencies>
  2. <!-- 核心启动器(自动配置MyBatis-Plus) -->
  3. <dependency>
  4. <groupId>com.baomidou</groupId>
  5. <artifactId>mybatis-plus-boot-starter</artifactId>
  6. <version>3.5.3.1</version>
  7. </dependency>
  8. <!-- 数据库驱动(以MySQL为例) -->
  9. <dependency>
  10. <groupId>mysql</groupId>
  11. <artifactId>mysql-connector-java</artifactId>
  12. <scope>runtime</scope>
  13. </dependency>
  14. <!-- 可选:Lombok简化实体类开发 -->
  15. <dependency>
  16. <groupId>org.projectlombok</groupId>
  17. <artifactId>lombok</artifactId>
  18. <optional>true</optional>
  19. </dependency>
  20. </dependencies>

建议通过Spring Initializr创建项目时勾选”MyBatis Framework”和”MySQL Driver”,IDE会自动生成基础依赖结构。

1.2 数据源配置优化

application.yml中配置多环境数据源时,推荐采用YAML的Profiles特性:

  1. spring:
  2. datasource:
  3. driver-class-name: com.mysql.cj.jdbc.Driver
  4. # 公共配置
  5. hikari:
  6. maximum-pool-size: 15
  7. connection-timeout: 30000
  8. ---
  9. spring:
  10. profiles: dev
  11. datasource:
  12. url: jdbc:mysql://localhost:3306/dev_db?useSSL=false
  13. username: dev_user
  14. password: dev@123
  15. ---
  16. spring:
  17. profiles: prod
  18. datasource:
  19. url: jdbc:mysql://rds-instance.example.com:3306/prod_db
  20. username: prod_admin
  21. password: ${ENCRYPTED_PASSWORD}

生产环境建议使用配置中心(如Nacos)管理敏感信息,结合Jasypt等加密工具保护数据库密码。

1.3 实体类设计规范

遵循以下原则设计实体类:

  1. 表映射注解:使用@TableName指定表名,避免默认下划线转换问题
  2. 主键策略:推荐使用雪花算法IdType.ASSIGN_ID替代数据库自增
  3. 字段类型映射:注意Java类型与数据库类型的精确对应

示例实体类:

  1. @Data
  2. @TableName("sys_user")
  3. public class User {
  4. @TableId(type = IdType.ASSIGN_ID)
  5. private Long id;
  6. @TableField("user_name") // 字段名映射
  7. private String username;
  8. @TableField(value = "create_time", fill = FieldFill.INSERT) // 自动填充
  9. private LocalDateTime createTime;
  10. @TableLogic // 逻辑删除
  11. private Integer deleted;
  12. }

二、核心功能实现

2.1 CRUD操作进阶

基础操作示例

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserMapper userMapper;
  5. // 插入(返回影响行数)
  6. public int addUser(User user) {
  7. return userMapper.insert(user);
  8. }
  9. // 批量插入(MyBatis-Plus 3.5.0+支持)
  10. public boolean batchInsert(List<User> users) {
  11. return userMapper.insertBatchSomeColumn(users) == users.size();
  12. }
  13. }

条件构造器详解

Wrapper是MyBatis-Plus的核心组件,支持链式调用:

  1. // 复杂查询示例
  2. public List<User> queryUsers(String name, Integer minAge) {
  3. QueryWrapper<User> wrapper = new QueryWrapper<>();
  4. wrapper.like("user_name", name)
  5. .ge("age", minAge)
  6. .orderByDesc("create_time")
  7. .last("limit 10"); // 追加原生SQL
  8. return userMapper.selectList(wrapper);
  9. }
  10. // Lambda表达式写法(类型安全)
  11. public User getUserById(Long id) {
  12. LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
  13. wrapper.eq(User::getId, id)
  14. .select(User::getId, User::getUsername);
  15. return userMapper.selectOne(wrapper);
  16. }

2.2 分页查询实现

配置分页插件后即可使用Page对象:

  1. @Configuration
  2. public class MybatisPlusConfig {
  3. @Bean
  4. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  5. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  6. interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
  7. return interceptor;
  8. }
  9. }
  10. // 服务层实现
  11. public PageResult<User> pageQuery(int pageNum, int pageSize) {
  12. Page<User> page = new Page<>(pageNum, pageSize);
  13. LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
  14. wrapper.eq(User::getDeleted, 0);
  15. IPage<User> result = userMapper.selectPage(page, wrapper);
  16. return new PageResult<>(result.getRecords(),
  17. result.getTotal(),
  18. pageNum,
  19. pageSize);
  20. }

三、高级特性应用

3.1 动态表名策略

实现TableNameHandler接口支持动态表名:

  1. @Component
  2. public class DynamicTableNameHandler implements TableNameHandler {
  3. @Override
  4. public String dynamicTableName(String sql, String tableName) {
  5. // 根据业务逻辑返回实际表名
  6. String dateSuffix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
  7. return tableName + "_" + dateSuffix;
  8. }
  9. }
  10. // 配置动态表名解析器
  11. @Bean
  12. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  13. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  14. DynamicTableNameInnerInterceptor dynamicInterceptor = new DynamicTableNameInnerInterceptor();
  15. dynamicInterceptor.setTableNameHandler(dynamicTableNameHandler);
  16. interceptor.addInnerInterceptor(dynamicInterceptor);
  17. return interceptor;
  18. }

3.2 性能优化方案

  1. SQL执行分析:开启MyBatis-Plus的SQL性能分析插件

    1. mybatis-plus:
    2. global-config:
    3. sql-parser-cache: true
    4. configuration:
    5. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  2. 批量操作优化:使用saveBatch方法时配置批量大小

    1. // 自定义批量大小(默认1000)
    2. @Transactional(rollbackFor = Exception.class)
    3. public void batchInsert(List<User> users) {
    4. userMapper.insertBatchSomeColumn(users);
    5. // 或使用Service层的saveBatch
    6. // userService.saveBatch(users, 500);
    7. }
  3. 二级缓存配置:在Mapper接口添加@CacheNamespace注解

    1. @CacheNamespace(implementation = PerpetualCache.class,
    2. eviction = LruCache.class,
    3. flushInterval = 60000)
    4. public interface UserMapper extends BaseMapper<User> {
    5. // ...
    6. }

四、最佳实践建议

  1. 统一异常处理:结合@ControllerAdvice捕获MybatisPlusException
  2. DTO转换:使用MapStruct等工具实现Entity与DTO的自动转换
  3. 代码生成器:通过MyBatis-Plus Generator快速生成基础代码
  4. 多数据源:使用AbstractRoutingDataSource实现动态数据源切换
  5. 防SQL注入:始终使用Wrapper构建查询条件,避免字符串拼接

通过系统掌握上述技术方案,开发团队可显著提升数据库操作效率,减少80%以上的CRUD代码量,同时保持代码的可读性和可维护性。建议在实际项目中结合Spring Security实现细粒度的数据权限控制,构建企业级的数据访问层解决方案。