1. SpringBoot整合MyBatis操作MySQL实战指南
在企业级Java开发中,数据持久化是每个系统必须面对的核心问题。SpringBoot作为当下最流行的Java应用框架,与MyBatis这个半自动ORM工具的搭配,形成了轻量级且高效的数据访问解决方案。本文将手把手带你完成从环境搭建到完整查询的全流程实现,包含我在实际项目中总结的7个关键优化点。
2. 环境准备与项目初始化
2.1 开发环境配置
推荐使用以下环境组合:
- JDK 1.8+(实测兼容性最佳)
- Maven 3.6.3(注意配置阿里云镜像)
- IntelliJ IDEA 2022+(社区版足够)
- MySQL 8.0.28(5.7版本需调整部分配置)
重要提示:MySQL 8.x默认使用caching_sha2_password认证,旧版客户端连接时会报错。解决方案是在my.ini中添加:
[mysqld] default_authentication_plugin=mysql_native_password
2.2 项目骨架搭建
使用Spring Initializr生成项目时,必须勾选:
- Spring Web(用于构建Controller层)
- MyBatis Framework(核心依赖)
- MySQL Driver(数据库连接)
pom.xml关键依赖版本建议:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> <version>8.0.28</version> </dependency>3. 数据库层深度配置
3.1 数据源最佳实践
application.yml配置示例:
spring: datasource: url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 20 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 18000003.2 MyBatis配置技巧
在resources下新建mybatis-config.xml:
<configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="jdbcTypeForNull" value="NULL"/> </settings> <typeAliases> <package name="com.example.demo.entity"/> </typeAliases> </configuration>4. 核心代码实现
4.1 实体类设计
采用Lombok简化代码:
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class User { private Long id; private String username; private String email; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; }4.2 Mapper接口开发
推荐使用注解与XML混合模式:
@Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User selectById(@Param("id") Long id); @Insert("INSERT INTO user(username,email) VALUES(#{user.username},#{user.email})") @Options(useGeneratedKeys = true, keyProperty = "id") int insert(@Param("user") User user); }4.3 Service层事务控制
@Service @RequiredArgsConstructor public class UserService { private final UserMapper userMapper; @Transactional(rollbackFor = Exception.class) public Long createUser(UserDTO dto) { User user = User.builder() .username(dto.getUsername()) .email(dto.getEmail()) .createTime(LocalDateTime.now()) .build(); userMapper.insert(user); return user.getId(); } }5. 性能优化实战
5.1 二级缓存配置
在mapper接口上添加:
@CacheNamespace(implementation = MybatisRedisCache.class, eviction = MybatisRedisCache.class) public interface UserMapper { //...原有方法 }自定义Redis缓存实现:
public class MybatisRedisCache implements Cache { private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final String id; private final RedisTemplate<String, Object> redisTemplate; public MybatisRedisCache(String id) { this.id = id; this.redisTemplate = (RedisTemplate<String, Object>) SpringContextHolder.getBean("redisTemplate"); } //...实现Cache接口方法 }5.2 批量插入优化
@Insert("<script>" + "INSERT INTO user(username, email) VALUES " + "<foreach collection='list' item='item' separator=','>" + "(#{item.username}, #{item.email})" + "</foreach>" + "</script>") void batchInsert(@Param("list") List<User> users);6. 常见问题排查
6.1 字段映射失败
现象:查询返回null值 解决方案:
- 检查数据库字段名与实体类属性名是否匹配
- 确认是否开启mapUnderscoreToCamelCase
- 使用@Results注解显式指定映射关系
6.2 事务失效场景
典型原因:
- 方法非public修饰
- 自调用问题(this.method())
- 异常类型不匹配(默认只回滚RuntimeException)
- 数据库引擎不支持(如MyISAM)
6.3 连接池耗尽
监控指标:
HikariDataSource dataSource = (HikariDataSource) applicationContext.getBean("dataSource"); log.info("活跃连接数:{}", dataSource.getHikariPoolMXBean().getActiveConnections());7. 生产环境建议
- SQL监控:集成Druid或P6Spy打印真实SQL
- 慢查询阈值设置为500ms
- 定期执行ANALYZE TABLE更新统计信息
- 使用ShardingSphere进行分库分表
- 为常用查询字段添加合适索引
我在金融级项目中验证过的配置参数:
mybatis: configuration: default-fetch-size: 100 default-statement-timeout: 30 lazy-loading-enabled: true aggressive-lazy-loading: false