Spring Boot整合MyBatis:从基础配置到高级应用
2026/7/22 2:49:55 网站建设 项目流程

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 WebMyBatis Framework和对应数据库驱动(如MySQL Driver
  • POM关键依赖
<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</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?useSSL=false&serverTimezone=UTC username: root password: 123456 hikari: maximum-pool-size: 15 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000

实测中发现三个易错点:

  1. 时区问题:MySQL 8.x必须指定serverTimezone参数
  2. SSL警告:开发环境建议显式关闭useSSL
  3. 连接泄漏:建议设置合理的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 version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UserMapper"> <resultMap id="userMap" type="com.example.entity.User"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="create_time" property="createTime"/> </resultMap> <select id="selectAll" resultMap="userMap"> SELECT * FROM t_user </select> </mapper>

需在application.yml添加配置:

mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity

3. 高级特性实战应用

3.1 动态SQL构建

MyBatis提供强大的动态SQL能力:

<select id="searchUsers" resultMap="userMap"> SELECT * FROM t_user <where> <if test="username != null"> AND username LIKE CONCAT('%', #{username}, '%') </if> <if test="startTime != null"> AND create_time >= #{startTime} </if> </where> ORDER BY id DESC </select>

对应Java接口:

List<User> 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); // 其他数据库操作 } }

关键注意事项:

  1. 事务方法必须public
  2. 默认只回滚RuntimeException
  3. 同类方法调用不会触发事务代理

4. 性能优化与生产实践

4.1 二级缓存配置

在application.yml中启用缓存:

mybatis: configuration: cache-enabled: true

Mapper接口添加注解:

@CacheNamespace public interface UserMapper { // 方法定义 }

警告:分布式环境需要配合Redis等实现自定义缓存

4.2 分页插件集成

添加PageHelper依赖:

<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>

使用示例:

PageHelper.startPage(1, 10); List<User> users = userMapper.selectAll(); PageInfo<User> 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

解决方案检查清单:

  1. 确认接口有@Mapper注解或主类有@MapperScan
  2. 检查mapper-locations路径是否正确
  3. 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)

可能原因:

  1. #{param}被写成了${param}
  2. @Param注解缺失
  3. XML中parameterType与实际不符

5.3 事务不生效场景

典型情况:

  1. 方法非public
  2. 异常被catch未抛出
  3. 数据库引擎不支持(如MyISAM)
  4. 同类方法自调用

排查步骤:

  1. 检查日志是否有"Creating new transaction"
  2. 确认代理模式(建议使用CGLIB)
  3. 测试异常是否触发回滚

6. 扩展功能开发实践

6.1 自定义TypeHandler

处理枚举类型示例:

@MappedTypes(UserType.class) public class UserTypeHandler extends BaseTypeHandler<UserType> { @Override public void setNonNullParameter(PreparedStatement ps, int i, UserType parameter, JdbcType jdbcType) { ps.setInt(i, parameter.getCode()); } // 其他抽象方法实现... }

注册TypeHandler:

mybatis: type-handlers-package: com.example.handler

6.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.sql

7.3 集成测试示例

REST API测试示例:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) class UserControllerTest { @LocalServerPort private int port; @Autowired private TestRestTemplate restTemplate; @Test void testGetUser() { ResponseEntity<User> 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.active=prod

8.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:MaxGCPauseMillis=200 -XX:ParallelGCThreads=4

MyBatis额外配置:

mybatis: configuration: default-fetch-size: 100 default-statement-timeout: 30

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询