Spring Boot项目里MyBatis到底怎么配?从XML映射到缓存开启,一份完整的配置清单
Spring Boot与MyBatis深度整合实战指南
1. 项目初始化与环境准备
在开始Spring Boot与MyBatis的整合之前,我们需要确保开发环境已经准备就绪。首先创建一个基础的Spring Boot项目,推荐使用Spring Initializr(https://start.spring.io/)进行快速初始化。在选择依赖时,务必勾选以下核心模块:
- Spring Web :用于构建Web应用的基础支持
- MyBatis Framework :MyBatis的Spring Boot官方starter
- MySQL Driver 或其他数据库驱动:根据实际使用的数据库选择
初始化完成后,项目结构应该包含以下关键目录:
src/main/java
└─com.example.demo
├─config # 自定义配置类
├─controller # Web层
├─service # 业务逻辑层
├─mapper # 数据访问层接口
└─entity # 实体类
src/main/resources
├─static
├─templates
└─application.yml # 主配置文件
2. 基础配置详解
2.1 数据源配置
在application.yml中配置数据源是整合的第一步。Spring Boot提供了简洁的配置方式:
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_db?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: yourpassword
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 15
minimum-idle: 5
connection-timeout: 30000
提示:生产环境中密码应该使用加密配置,推荐使用Jasypt等工具进行敏感信息加密
2.2 MyBatis基础配置
在application.yml中添加MyBatis相关配置:
mybatis:
mapper-locations: classpath:mapper/*.xml # XML映射文件位置
type-aliases-package: com.example.demo.entity # 实体类包路径
configuration:
map-underscore-to-camel-case: true # 自动驼峰命名转换
default-fetch-size: 100
default-statement-timeout: 30
2.3 XML映射与接口绑定
MyBatis的核心特性之一就是接口与XML的绑定。创建一个简单的用户查询示例:
- 首先定义实体类:
package com.example.demo.entity;
public class User {
private Long id;
private String username;
private String email;
// getters and setters
}
- 创建Mapper接口:
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
User selectById(Long id);
}
- 编写对应的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.demo.mapper.UserMapper">
<resultMap id="BaseResultMap" type="User">
<id column="id" property="id" />
<result column="username" property="username" />
<result column="email" property="email" />
</resultMap>
<select id="selectById" resultMap="BaseResultMap">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
3. 高级特性配置
3.1 缓存机制详解
MyBatis提供了一级缓存和二级缓存机制,合理使用可以显著提升性能。
一级缓存 (默认开启):
- 作用域:SqlSession级别
- 特点:同一个SqlSession中相同的查询会直接返回缓存结果
- 失效条件:执行增删改操作、调用clearCache()、关闭SqlSession
二级缓存配置 : 在application.yml中开启二级缓存:
mybatis:
configuration:
cache-enabled: true
在Mapper接口上添加注解:
@CacheNamespace
public interface UserMapper {
// 方法定义
}
或者在XML映射文件中配置:
<mapper namespace="com.example.demo.mapper.UserMapper">
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
<!-- 其他配置 -->
</mapper>
3.2 动态SQL实践
MyBatis强大的动态SQL能力可以让我们灵活构建查询条件。以下是几个常用场景:
条件查询示例 :
<select id="selectUsers" resultMap="BaseResultMap">
SELECT * FROM user
<where>
<if test="username != null">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="email != null">
AND email = #{email}
</if>
<if test="statusList != null and statusList.size() > 0">
AND status IN
<foreach collection="statusList" item="status" open="(" separator="," close=")">
#{status}
</foreach>
</if>
</where>
ORDER BY create_time DESC
</select>
更新语句示例 :
<update id="updateSelective" parameterType="User">
UPDATE user
<set>
<if test="username != null">username = #{username},</if>
<if test="email != null">email = #{email},</if>
</set>
WHERE id = #{id}
</update>
4. 性能优化与最佳实践
4.1 分页查询实现
MyBatis与Spring Boot整合时,推荐使用PageHelper实现物理分页:
- 添加依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
- 在application.yml中配置:
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
- 使用示例:
public PageInfo<User> getUsers(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
return new PageInfo<>(users);
}
4.2 批量操作优化
对于批量插入或更新操作,MyBatis提供了高效的实现方式:
批量插入示例 :
@Insert("<script>" +
"INSERT INTO user (username, email) VALUES " +
"<foreach collection='list' item='item' separator=','>" +
"(#{item.username}, #{item.email})" +
"</foreach>" +
"</script>")
void batchInsert(List<User> users);
批量更新示例 :
<update id="batchUpdate">
<foreach collection="list" item="item" separator=";">
UPDATE user
SET username = #{item.username}, email = #{item.email}
WHERE id = #{item.id}
</foreach>
</update>
注意:批量操作时需要考虑数据库对SQL语句长度的限制,建议每批处理100-1000条数据
4.3 复杂查询结果映射
对于一对多、多对多等复杂关系,MyBatis提供了强大的结果映射能力:
<resultMap id="UserWithOrdersMap" type="User" extends="BaseResultMap">
<collection property="orders" ofType="Order">
<id column="order_id" property="id"/>
<result column="order_no" property="orderNo"/>
<result column="order_amount" property="amount"/>
</collection>
</resultMap>
<select id="selectUserWithOrders" resultMap="UserWithOrdersMap">
SELECT
u.*,
o.id as order_id,
o.order_no,
o.amount as order_amount
FROM user u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
5. 常见问题排查
5.1 配置不生效问题
当发现配置没有按预期生效时,可以按照以下步骤排查:
- 检查配置文件的加载顺序和优先级
- 确认没有在多个位置重复配置相互冲突的属性
- 检查依赖版本是否兼容
- 查看启动日志中的自动配置报告
5.2 SQL注入防范
虽然MyBatis的#{}语法已经可以防止大部分SQL注入,但仍需注意:
- 永远不要使用${}拼接用户输入的参数
- 对于like查询,应该在Java代码中处理通配符,而不是在SQL中
- 定期检查Mapper中的SQL语句安全性
5.3 事务管理
Spring Boot中整合MyBatis的事务管理非常简单:
@Service
@Transactional
public class UserService {
private final UserMapper userMapper;
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Transactional(rollbackFor = Exception.class)
public void updateUser(User user) {
userMapper.update(user);
// 其他数据库操作
}
}
关键点:
- 使用@Transactional注解声明事务
- 默认只对RuntimeException回滚,可通过rollbackFor指定其他异常类型
- 事务方法应该放在Service层,而不是Controller层
更多推荐


所有评论(0)