MyBatis-Flex与SpringBoot整合开发实战指南 1. 为什么选择MyBatis-Flex与SpringBoot整合MyBatis-Flex作为MyBatis的增强框架在传统ORM基础上提供了更灵活的动态SQL支持。与SpringBoot这个约定优于配置的微服务框架结合能显著提升开发效率。我在实际项目中发现这种组合特别适合需要快速迭代的中小型项目。传统MyBatis需要手动编写大量XML映射文件而MyBatis-Flex通过注解和链式API让代码量减少40%以上。比如多表联查场景原先需要写复杂的resultMap现在通过Table注解和Relations注解就能轻松实现。2. 环境准备与项目初始化2.1 必备工具清单JDK 1.8推荐Amazon Corretto 17IntelliJ IDEA 2023.2社区版足够Maven 3.6.3MySQL 8.0或H2内存数据库用于测试2.2 创建SpringBoot项目通过start.spring.io生成项目时除了选择Web和MySQL驱动外特别注意使用SpringBoot 2.7.x版本目前最稳定打包方式选jarJava版本选17!-- pom.xml关键依赖 -- dependency groupIdcom.mybatis-flex/groupId artifactIdmybatis-flex-spring-boot-starter/artifactId version1.2.8/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency3. 核心配置详解3.1 数据源配置application.yml中需要特别注意连接池配置spring: datasource: url: jdbc:mysql://localhost:3306/flex_demo?useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 hikari: maximum-pool-size: 20 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 mybatis-flex: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志3.2 实体类映射User实体类的注解配置示例Table(sys_user) public class User { Id(keyType KeyType.Auto) private Long id; Column(username) private String name; Column(onInsertValue now()) private LocalDateTime createTime; // 关联部门1对1 RelationOneToOne(selfField deptId, targetField id) private Department department; }4. 增删改查实战4.1 基础CRUD操作// 插入自动填充创建时间 User user new User(); user.setName(张三); userMapper.insert(user); // 条件更新 User updateUser new User(); updateUser.setId(1L); updateUser.setName(李四); userMapper.update(updateUser); // 链式查询 ListUser users userMapper.selectListByQuery( Query.create().where(User::getName).like(张) .and(User::getCreateTime).ge(LocalDate.now()) .orderBy(User::getId, false) );4.2 复杂查询示例多表联查的三种实现方式注解关联推荐Table(sys_order) public class Order { RelationManyToOne(selfField userId, targetField id) private User user; }手动JoinQueryWrapper query QueryWrapper.create() .select(ORDER.ALL_COLUMNS, USER.USER_NAME) .from(ORDER) .leftJoin(USER).on(ORDER.USER_ID.eq(USER.ID)) .where(ORDER.AMOUNT.gt(1000));子查询QueryWrapper query QueryWrapper.create() .select() .from(USER) .where(USER.ID.in( select(ORDER.USER_ID).from(ORDER).where(ORDER.STATUS.eq(1)) ));5. 高级特性应用5.1 动态表名适合多租户场景public class TenantTable implements TableProcessor { Override public String process(String tableName) { return TenantContext.getTenantId() _ tableName; } } // 配置启用 mybatis-flex: table-processor: com.example.TenantTable5.2 逻辑删除全局配置逻辑删除字段mybatis-flex: global-config: logic-delete: column: is_deleted logic-not-delete-value: 0 logic-delete-value: 15.3 数据脱敏使用ColumnMask注解ColumnMask(Masks.CHINESE_NAME) private String realName; ColumnMask(Masks.MOBILE) private String phone;6. 性能优化建议批量操作使用executeBatchtry (SqlSession session sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper mapper session.getMapper(UserMapper.class); for (int i 0; i 1000; i) { mapper.insert(new User(useri)); } session.commit(); }复杂查询开启二级缓存Cache(flushInterval 300000) // 5分钟刷新 public interface UserMapper extends BaseMapperUser { Cache ListUser selectSpecialUsers(); }避免N1查询// 错误做法会触发N1 ListOrder orders orderMapper.selectAll(); orders.forEach(o - System.out.println(o.getUser().getName())); // 正确做法一次加载 ListOrder orders orderMapper.selectListWithRelations( Query.create().all().withRelations(user) );7. 常见问题排查7.1 字段映射失败症状查询结果字段为null 排查步骤检查Column注解的value是否与数据库列名一致确认数据库字段是否为下划线命名默认开启下划线转驼峰在application.yml添加配置mybatis-flex: configuration: map-underscore-to-camel-case: true7.2 事务不生效确保主类有EnableTransactionManagement方法上有Transactional不要try-catch吞掉异常同类方法调用走代理通过Autowired注入自己7.3 分页查询异常正确使用姿势PageUser page Page.of(1, 10); // 第1页每页10条 QueryWrapper query QueryWrapper.create() .where(User::getStatus).eq(1) .orderBy(User::getId.desc()); PageUser result userMapper.paginate(page, query);8. 生产环境建议监控SQL性能mybatis-flex: metrics: enabled: true logger: enabled: true level: warn warn-time: 1000 # 超过1秒的SQL告警多数据源配置Configuration MapperScan(basePackages com.dao.db1, sqlSessionFactoryRef db1SqlSessionFactory) public class Db1Config { Bean ConfigurationProperties(spring.datasource.db1) public DataSource db1DataSource() { return DataSourceBuilder.create().build(); } Bean public SqlSessionFactory db1SqlSessionFactory() throws Exception { MybatisFlexSqlSessionFactoryBean factory new MybatisFlexSqlSessionFactoryBean(); factory.setDataSource(db1DataSource()); return factory.getObject(); } }线上问题排查工具开启SQL日志时添加MDC标记logging: pattern: console: %d{yyyy-MM-dd HH:mm:ss} [%X{traceId}] %-5level %logger{36} - %msg%n我在实际项目中发现MyBatis-Flex的Relation注解虽然方便但在处理超大规模数据关联时10万记录会有性能问题。这时建议改用手动Join配合分页查询。另外字段加密功能对模糊查询支持有限如果业务需要模糊搜索加密字段可以考虑在数据库层使用加密函数索引。