Spring与MyBatis整合开发实战指南 1. Spring与MyBatis整合概述在企业级Java开发中Spring框架和MyBatis持久层框架的组合堪称黄金搭档。我使用这套技术栈已有8年时间从早期的XML配置到现在的注解驱动见证了整个技术演进过程。这种组合既能享受Spring的IoC容器管理和事务控制又能利用MyBatis灵活的SQL映射能力特别适合需要精细控制SQL又不想放弃ORM便利性的场景。2. 环境准备与基础配置2.1 依赖管理使用Maven构建项目时需要引入以下核心依赖以Spring Boot为例dependencies !-- Spring Boot Starter -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter/artifactId /dependency !-- MyBatis Spring Boot Starter -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version3.0.3/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency /dependencies注意MyBatis Starter的版本需要与Spring Boot版本匹配不兼容的版本组合会导致奇怪的异常。2.2 数据源配置在application.yml中配置数据源spring: datasource: url: jdbc:mysql://localhost:3306/your_db?useSSLfalseserverTimezoneUTC username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 20 minimum-idle: 53. MyBatis核心配置详解3.1 映射器接口与XML配置创建Mapper接口Mapper public interface UserMapper { Select(SELECT * FROM users WHERE id #{id}) User findById(Long id); Insert(INSERT INTO users(name,email) VALUES(#{name},#{email})) Options(useGeneratedKeys true, keyProperty id) int insert(User user); }或者使用XML映射文件推荐复杂SQL使用!-- UserMapper.xml -- mapper namespacecom.example.mapper.UserMapper select idfindByEmail resultTypecom.example.model.User SELECT * FROM users WHERE email #{email} /select /mapper3.2 动态SQL实践MyBatis强大的动态SQL能力select idsearchUsers resultTypeUser SELECT * FROM users where if testname ! null AND name LIKE CONCAT(%,#{name},%) /if if testemail ! null AND email #{email} /if if testids ! null and ids.size() 0 AND id IN foreach itemid collectionids open( separator, close) #{id} /foreach /if /where ORDER BY id DESC /select4. 高级整合技巧4.1 分页插件集成添加PageHelper分页插件Configuration public class MyBatisConfig { Bean public PageInterceptor pageInterceptor() { PageInterceptor pageInterceptor new PageInterceptor(); Properties properties new Properties(); properties.setProperty(helperDialect, mysql); properties.setProperty(reasonable, true); pageInterceptor.setProperties(properties); return pageInterceptor; } }使用示例PageHelper.startPage(1, 10); // 第1页每页10条 ListUser users userMapper.selectAll(); PageInfoUser pageInfo new PageInfo(users);4.2 多数据源配置配置多个数据源Configuration MapperScan(basePackages com.example.primary.mapper, sqlSessionFactoryRef primarySqlSessionFactory) public class PrimaryDataSourceConfig { Bean ConfigurationProperties(spring.datasource.primary) public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } Bean public SqlSessionFactory primarySqlSessionFactory( Qualifier(primaryDataSource) DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); factoryBean.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/primary/*.xml)); return factoryBean.getObject(); } Bean public DataSourceTransactionManager primaryTransactionManager( Qualifier(primaryDataSource) DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }5. 性能优化与最佳实践5.1 二级缓存配置启用MyBatis二级缓存!-- 在mapper.xml中 -- cache evictionLRU flushInterval60000 size512 readOnlytrue/Spring中配置缓存管理器Bean public CacheManager cacheManager() { EhCacheCacheManager cacheManager new EhCacheCacheManager(); cacheManager.setCacheManager( EhCacheManagerUtils.buildCacheManager( new ClassPathResource(ehcache.xml))); return cacheManager; }5.2 批量操作优化使用批量插入提升性能Insert(script INSERT INTO users(name, email) VALUES foreach collectionusers itemuser separator, (#{user.name}, #{user.email}) /foreach /script) void batchInsert(Param(users) ListUser users);或者使用ExecutorType.BATCHAutowired private SqlSessionTemplate sqlSessionTemplate; public void batchInsert(ListUser users) { SqlSession session sqlSessionTemplate.getSqlSessionFactory() .openSession(ExecutorType.BATCH, false); try { UserMapper mapper session.getMapper(UserMapper.class); for (User user : users) { mapper.insert(user); } session.commit(); } finally { session.close(); } }6. 常见问题排查6.1 映射问题排查当遇到属性映射失败时检查数据库字段名与Java属性名是否匹配确认是否使用了正确的resultType/resultMap尝试在SQL中使用AS重命名列select idfindUser resultTypeUser SELECT user_id AS id, user_name AS name, user_email AS email FROM t_user WHERE user_id #{id} /select6.2 事务不生效场景确保事务生效的要点检查方法是否为public确认是否在同一个类中调用验证Transactional注解是否正确配置Service public class UserService { Transactional(rollbackFor Exception.class) public void updateUser(User user) { // 业务逻辑 } }7. 现代Spring Boot整合方案7.1 自动配置原理Spring Boot自动配置的关键类MybatisAutoConfigurationMybatisLanguageDriverAutoConfigurationMybatisPlusAutoConfiguration (如果使用MyBatis-Plus)可以通过debug查看自动配置过程logging.level.org.springframework.boot.autoconfigureDEBUG7.2 最新功能整合使用Spring Boot 3.x的新特性Mapper public interface UserMapper { Select( SELECT * FROM users WHERE create_time #{createTime} ) ListUser findByCreateTime(Param(createTime) LocalDateTime createTime); }文本块语法让SQL更清晰可读。8. 监控与性能分析8.1 SQL监控配置集成P6Spy打印真实SQLspring.datasource.driver-class-namecom.p6spy.engine.spy.P6SpyDriver spring.datasource.urljdbc:p6spy:mysql://localhost:3306/test配置spy.propertiesmodule.logcom.p6spy.engine.logging.P6LogFactory appendercom.p6spy.engine.spy.appender.Slf4JLogger logMessageFormatcom.p6spy.engine.spy.appender.CustomLineFormat customLogMessageFormat%(currentTime)|%(executionTime)|%(category)|%(sql)8.2 MyBatis指标暴露通过Actuator暴露MyBatis指标management.endpoints.web.exposure.includehealth,info,metrics,mybatis然后可以访问/actuator/metrics/mybatis.executions获取执行统计。