MyBatis-Plus深度实践:从核心功能到高阶扩展

一、多数据源管理与分库分表策略

在大型分布式系统中,数据库性能瓶颈是常见挑战。当单库数据量超过千万级时,常规SQL查询的响应时间显著增加,此时需要采用分库分表技术。MyBatis-Plus通过动态数据源组件实现了多数据源的灵活管理,开发者可通过@DS注解在Service层指定数据源:

  1. @Service
  2. @DS("slave") // 指定从库数据源
  3. public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
  4. @DS("master") // 方法级别覆盖类注解
  5. public void updateOrder(Order order) {
  6. // 写操作走主库
  7. }
  8. }

分库分表策略需结合ShardingSphere等中间件实现,常见方案包括:

  1. 水平分片:按哈希值或范围将数据分散到不同表
  2. 垂直分片:按业务维度拆分表结构
  3. 复合分片:结合水平与垂直分片策略

实际项目中,建议将分片规则配置在配置文件中:

  1. spring:
  2. shardingsphere:
  3. sharding:
  4. tables:
  5. t_order:
  6. actual-data-nodes: ds$->{0..1}.t_order_$->{0..15}
  7. table-strategy:
  8. inline:
  9. sharding-column: order_id
  10. algorithm-expression: t_order_$->{order_id % 16}

二、并发控制与数据一致性保障

1. 乐观锁实现机制

在电商秒杀等高并发场景下,数据更新冲突频繁发生。MyBatis-Plus通过@Version注解实现乐观锁控制:

  1. @Data
  2. @TableName("t_inventory")
  3. public class Inventory {
  4. @Version // 版本号字段
  5. private Integer version;
  6. private Integer stock;
  7. }

执行更新时,框架自动生成带版本号校验的SQL:

  1. UPDATE t_inventory
  2. SET stock=stock-1, version=version+1
  3. WHERE id=1 AND version=3

若版本号不匹配,抛出OptimisticLockingFailureException异常,开发者可捕获后进行重试或补偿操作。

2. 防全表更新插件

为避免误操作导致的数据灾难,建议配置防全表更新插件:

  1. @Configuration
  2. public class MybatisPlusConfig {
  3. @Bean
  4. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  5. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  6. // 添加防全表更新插件
  7. interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  8. return interceptor;
  9. }
  10. }

该插件会拦截包含update table_name(无where条件)的SQL语句,直接抛出异常阻止执行。

三、开发效率提升工具链

1. 智能代码生成器

MyBatis-Plus提供的代码生成器可自动生成Entity/Mapper/Service等标准层代码。通过配置模板引擎(如Velocity/Freemarker),可定制化输出:

  1. public class CodeGenerator {
  2. public static void main(String[] args) {
  3. AutoGenerator generator = new AutoGenerator();
  4. // 全局配置
  5. GlobalConfig gc = new GlobalConfig();
  6. gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
  7. gc.setAuthor("dev_team");
  8. generator.setGlobalConfig(gc);
  9. // 数据源配置
  10. DataSourceConfig dsc = new DataSourceConfig();
  11. dsc.setUrl("jdbc:mysql://localhost:3306/test");
  12. generator.setDataSource(dsc);
  13. // 策略配置
  14. StrategyConfig strategy = new StrategyConfig();
  15. strategy.setNaming(NamingStrategy.underline_to_camel);
  16. strategy.setEntityLombokModel(true);
  17. generator.setStrategy(strategy);
  18. generator.execute();
  19. }
  20. }

2. SQL执行分析插件

生产环境调试SQL时,可通过SQL分析插件记录完整执行日志:

  1. @Bean
  2. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  3. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  4. // 添加SQL分析插件
  5. interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());
  6. return interceptor;
  7. }

配置日志级别为DEBUG后,控制台将输出:

  1. ==> Preparing: SELECT id,name,age FROM user WHERE age > ?
  2. ==> Parameters: 18(Integer)
  3. <== Total: 5

四、高级特性实践

1. ActiveRecord模式

该模式允许直接通过实体类操作数据库,适合简单CRUD场景:

  1. @TableName("t_user")
  2. public class User extends Model<User> {
  3. @TableId
  4. private Long id;
  5. private String name;
  6. public static User selectById(Long id) {
  7. return new User().selectById(id);
  8. }
  9. }
  10. // 使用示例
  11. User user = User.selectById(1L);
  12. user.setName("new_name");
  13. user.updateById();

2. 逻辑删除实现

物理删除存在数据恢复风险,推荐使用逻辑删除:

  1. @Data
  2. @TableName("t_order")
  3. public class Order {
  4. @TableLogic // 逻辑删除字段
  5. private Integer deleted;
  6. }

执行删除操作时,框架自动转换为更新语句:

  1. UPDATE t_order SET deleted=1 WHERE id=1

查询时自动过滤已删除数据,可通过@TableField注解自定义逻辑:

  1. @TableField(select = false) // 查询时不返回该字段
  2. private LocalDateTime deleteTime;

五、性能优化建议

  1. 批量操作优化:使用saveBatch()方法替代循环单条插入
  2. 分页查询优化:合理设置pageSize(建议20-100条)
  3. 缓存策略:对热点数据配置二级缓存
  4. SQL重写:复杂查询建议使用原生SQL或XML映射

通过合理配置连接池参数(如最大连接数、超时时间),可进一步提升系统吞吐量。建议结合APM工具监控SQL执行效率,针对性优化慢查询。

MyBatis-Plus作为MyBatis的增强工具,在保持原有功能的基础上,通过丰富的扩展组件显著提升了开发效率。开发者应深入理解其设计原理,根据业务场景选择合适的技术方案,构建稳定高效的数据库访问层。