
1. Spring Boot与MyBatis整合基础环境搭建1.1 项目初始化与依赖配置在IntelliJ IDEA中创建新的Spring Boot项目时推荐使用Spring Initializr向导。关键依赖选择需要注意以下配置项Spring Boot版本当前稳定版为3.2.x截至2024年对应Java 17环境。若需兼容Java 8需降级到2.7.x版本依赖勾选必须包含Spring Web、MyBatis Framework和对应数据库驱动如MySQL DriverPOM关键依赖dependencies dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version3.0.3/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency /dependencies注意mybatis-spring-boot-starter已自动包含MyBatis核心和MyBatis-Spring适配器无需单独引入1.2 数据库连接池配置Spring Boot默认使用HikariCP连接池在application.yml中配置示例spring: datasource: url: jdbc:mysql://localhost:3306/demo?useSSLfalseserverTimezoneUTC username: root password: 123456 hikari: maximum-pool-size: 15 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000实测中发现三个易错点时区问题MySQL 8.x必须指定serverTimezone参数SSL警告开发环境建议显式关闭useSSL连接泄漏建议设置合理的max-lifetime单位毫秒2. MyBatis核心组件配置详解2.1 实体类与Mapper接口定义实体类需要遵循JPA规范注解Data Table(name t_user) public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String username; private LocalDateTime createTime; }Mapper接口定义技巧Mapper public interface UserMapper { Select(SELECT * FROM t_user WHERE id #{id}) User findById(Long id); Insert(INSERT INTO t_user(username) VALUES(#{username})) Options(useGeneratedKeys true, keyProperty id) int insert(User user); }经验简单SQL推荐使用注解方式复杂SQL建议XML配置。MapperScan可批量扫描接口2.2 XML映射文件配置在resources/mapper目录下创建UserMapper.xml?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.mapper.UserMapper resultMap iduserMap typecom.example.entity.User id columnid propertyid/ result columnusername propertyusername/ result columncreate_time propertycreateTime/ /resultMap select idselectAll resultMapuserMap SELECT * FROM t_user /select /mapper需在application.yml添加配置mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity3. 高级特性实战应用3.1 动态SQL构建MyBatis提供强大的动态SQL能力select idsearchUsers resultMapuserMap SELECT * FROM t_user where if testusername ! null AND username LIKE CONCAT(%, #{username}, %) /if if teststartTime ! null AND create_time #{startTime} /if /where ORDER BY id DESC /select对应Java接口ListUser searchUsers(Param(username) String username, Param(startTime) LocalDateTime startTime);3.2 事务管理配置Spring Boot中启用事务管理Service RequiredArgsConstructor public class UserService { private final UserMapper userMapper; Transactional(rollbackFor Exception.class) public void createUser(User user) { userMapper.insert(user); // 其他数据库操作 } }关键注意事项事务方法必须public默认只回滚RuntimeException同类方法调用不会触发事务代理4. 性能优化与生产实践4.1 二级缓存配置在application.yml中启用缓存mybatis: configuration: cache-enabled: trueMapper接口添加注解CacheNamespace public interface UserMapper { // 方法定义 }警告分布式环境需要配合Redis等实现自定义缓存4.2 分页插件集成添加PageHelper依赖dependency groupIdcom.github.pagehelper/groupId artifactIdpagehelper-spring-boot-starter/artifactId version2.1.0/version /dependency使用示例PageHelper.startPage(1, 10); ListUser users userMapper.selectAll(); PageInfoUser pageInfo new PageInfo(users);4.3 监控与诊断Spring Boot Actuator集成management: endpoints: web: exposure: include: health,metrics,datasource关键监控指标hikaricp.connections.active活跃连接数hikaricp.connections.idle空闲连接数jdbc.connections.max最大连接数5. 常见问题排查指南5.1 启动时Mapper注入失败典型错误Field userMapper in com.example.service.UserService required a bean of type com.example.mapper.UserMapper that could not be found解决方案检查清单确认接口有Mapper注解或主类有MapperScan检查mapper-locations路径是否正确MyBatis版本与Spring Boot版本匹配5.2 SQL执行参数异常日志中看到### SQL: SELECT * FROM t_user WHERE id ? ### Cause: java.sql.SQLException: Parameter index out of range (1 number of parameters, which is 0)可能原因#{param}被写成了${param}Param注解缺失XML中parameterType与实际不符5.3 事务不生效场景典型情况方法非public异常被catch未抛出数据库引擎不支持如MyISAM同类方法自调用排查步骤检查日志是否有Creating new transaction确认代理模式建议使用CGLIB测试异常是否触发回滚6. 扩展功能开发实践6.1 自定义TypeHandler处理枚举类型示例MappedTypes(UserType.class) public class UserTypeHandler extends BaseTypeHandlerUserType { Override public void setNonNullParameter(PreparedStatement ps, int i, UserType parameter, JdbcType jdbcType) { ps.setInt(i, parameter.getCode()); } // 其他抽象方法实现... }注册TypeHandlermybatis: type-handlers-package: com.example.handler6.2 插件开发示例实现执行时间统计插件Intercepts(Signature(type StatementHandler.class, method query, args {Statement.class, ResultHandler.class})) public class PerformanceInterceptor implements Interceptor { Override public Object intercept(Invocation invocation) throws Throwable { long start System.currentTimeMillis(); try { return invocation.proceed(); } finally { long cost System.currentTimeMillis() - start; if (cost 100) { System.out.println(SQL执行耗时: cost ms); } } } }注册插件Configuration public class MyBatisConfig { Bean public PerformanceInterceptor performanceInterceptor() { return new PerformanceInterceptor(); } }7. 测试策略与技巧7.1 单元测试配置测试类基础配置SpringBootTest Transactional Rollback class UserMapperTest { Autowired private UserMapper userMapper; Test void testInsert() { User user new User(); user.setUsername(test); assertEquals(1, userMapper.insert(user)); assertNotNull(user.getId()); } }7.2 测试数据准备使用SQL脚本初始化数据-- src/test/resources/data.sql INSERT INTO t_user(username) VALUES(test1), (test2);测试配置spring: datasource: initialization-mode: always schema: classpath:schema.sql data: classpath:data.sql7.3 集成测试示例REST API测试示例SpringBootTest(webEnvironment WebEnvironment.RANDOM_PORT) class UserControllerTest { LocalServerPort private int port; Autowired private TestRestTemplate restTemplate; Test void testGetUser() { ResponseEntityUser response restTemplate.getForEntity( http://localhost: port /users/1, User.class); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNotNull(response.getBody().getUsername()); } }8. 生产环境部署建议8.1 多环境配置管理使用profile区分环境# application-dev.yml spring: datasource: url: jdbc:mysql://dev-db:3306/demo --- # application-prod.yml spring: datasource: url: jdbc:mysql://prod-db:3306/demo hikari: maximum-pool-size: 30启动命令java -jar app.jar --spring.profiles.activeprod8.2 健康检查配置自定义健康指标Component public class MyBatisHealthIndicator implements HealthIndicator { private final SqlSessionFactory sqlSessionFactory; Override public Health health() { try (SqlSession session sqlSessionFactory.openSession()) { session.selectOne(SELECT 1); return Health.up().build(); } catch (Exception e) { return Health.down(e).build(); } } }8.3 性能调优参数关键JVM参数建议-XX:UseG1GC -Xms1024m -Xmx1024m -XX:MaxGCPauseMillis200 -XX:ParallelGCThreads4MyBatis额外配置mybatis: configuration: default-fetch-size: 100 default-statement-timeout: 30