Appearance
MyBatis Spring Boot 集成
Spring Boot 与 MyBatis 的集成通过 mybatis-spring-boot-starter 实现,自动配置了 SqlSessionFactory、SqlSessionTemplate、Mapper 扫描等,让开发者几乎零配置即可使用 MyBatis。
一、依赖与配置
1.1 Maven 依赖
xml
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 数据库连接池(HikariCP 默认自带) -->
<!-- Druid 连接池(可选) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.20</version>
</dependency>1.2 application.yml 配置
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# HikariCP 连接池配置(默认)
hikari:
minimum-idle: 5
maximum-pool-size: 20
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
# MyBatis 配置
mybatis:
# Mapper XML 文件路径
mapper-locations: classpath:mapper/**/*.xml
# 实体类所在包(别名)
type-aliases-package: com.example.entity
# 全局配置
configuration:
# 驼峰命名
map-underscore-to-camel-case: true
# 日志
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
# 延迟加载
lazy-loading-enabled: true
aggressive-lazy-loading: false
# 缓存
cache-enabled: true
# 返回主键
use-generated-keys: true二、项目结构
src/main/java/com/example/
├── entity/
│ └── User.java # 实体类
├── mapper/
│ └── UserMapper.java # Mapper 接口
├── service/
│ ├── UserService.java # 接口
│ └── impl/
│ └── UserServiceImpl.java # 实现
└── controller/
└── UserController.java # 控制器
src/main/resources/
├── application.yml
└── mapper/
└── UserMapper.xml # Mapper XML三、代码示例
3.1 实体类
java
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private Date createTime;
}3.2 Mapper 接口
java
@Mapper // 或者使用 @MapperScan
public interface UserMapper {
User selectById(Long id);
List<User> selectAll();
int insert(User user);
int update(User user);
int deleteById(Long id);
}3.3 Mapper XML
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">
<select id="selectById" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<select id="selectAll" resultType="User">
SELECT * FROM user
</select>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>
<update id="update">
UPDATE user SET name=#{name}, age=#{age}, email=#{email} WHERE id=#{id}
</update>
<delete id="deleteById">
DELETE FROM user WHERE id = #{id}
</delete>
</mapper>3.4 Service 层
java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public User createUser(User user) {
userMapper.insert(user);
return user;
}
public User findById(Long id) {
return userMapper.selectById(id);
}
public List<User> findAll() {
return userMapper.selectAll();
}
@Transactional
public void updateUser(User user) {
userMapper.update(user);
}
@Transactional
public void deleteUser(Long id) {
userMapper.deleteById(id);
}
}3.5 Controller 层
java
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public Result<User> getUser(@PathVariable Long id) {
return Result.ok(userService.findById(id));
}
@GetMapping
public Result<List<User>> listUsers() {
return Result.ok(userService.findAll());
}
@PostMapping
public Result<User> createUser(@RequestBody User user) {
return Result.ok(userService.createUser(user));
}
@PutMapping("/{id}")
public Result<Void> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
userService.updateUser(user);
return Result.ok();
}
@DeleteMapping("/{id}")
public Result<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return Result.ok();
}
}四、@Mapper 与 @MapperScan
java
// 方式一:每个 Mapper 接口上标注 @Mapper(不推荐,每个都要加)
@Mapper
public interface UserMapper { }
// 方式二:启动类上使用 @MapperScan(推荐,一次扫描)
@SpringBootApplication
@MapperScan("com.example.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}五、事务集成
java
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private InventoryMapper inventoryMapper;
// MyBatis 的事务由 Spring 管理
@Transactional(rollbackFor = Exception.class)
public void createOrder(Order order) {
orderMapper.insert(order); // ① 插入订单
// ② 扣库存(如果失败,订单也会回滚)
int rows = inventoryMapper.deductStock(order.getProductId(), order.getQuantity());
if (rows == 0) {
throw new RuntimeException("库存不足");
}
}
}六、多数据源配置
yaml
spring:
datasource:
master:
url: jdbc:mysql://localhost:3306/db_master
username: root
password: 123456
slave:
url: jdbc:mysql://localhost:3307/db_slave
username: root
password: 123456java
@Configuration
@MapperScan(basePackages = "com.example.mapper.master",
sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
@Primary
@Bean(name = "masterDataSource")
@ConfigurationProperties("spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "masterSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/master/**/*.xml"));
return bean.getObject();
}
}七、打印 SQL 日志
yaml
# 方式一:MyBatis 配置
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 方式二:日志级别配置(推荐)
logging:
level:
com.example.mapper: DEBUG # 打印 SQL八、Spring Boot 自动配置原理
mybatis-spring-boot-starter 自动配置流程:
① MybatisAutoConfiguration 生效
→ 条件:存在 DataSource Bean、SqlSessionFactory 未手动创建
② 创建 SqlSessionFactory
→ 读取 mybatis.configuration.* 配置
→ 注册 Mapper XML(mybatis.mapper-locations)
→ 注册类型别名(mybatis.type-aliases-package)
③ 创建 SqlSessionTemplate
→ 线程安全的 SqlSession 实现
→ 代替 DefaultSqlSession
④ MapperScannerRegistrar 扫描 Mapper 接口
→ @MapperScan 指定的包或 @Mapper 标注的接口
→ 生成 MapperProxy 代理对象九、速记总结
Spring Boot 集成 MyBatis 三步走:
① 加依赖:mybatis-spring-boot-starter + 数据库驱动
② 配文件:数据源 + mybatis.mapper-locations + 驼峰映射
③ 写代码:@Mapper 接口 + XML 映射 + @Service + @Controller
关键注解:
@MapperScan → 扫描 Mapper 接口
@Mapper → 标注单个 Mapper
@Transactional → 事务管理
速记口诀:
依赖加配置,@MapperScan 扫接口,
XML 写 SQL,Service 加事务,Controller 调 Service。十、面试要点
| 问题 | 答案要点 |
|---|---|
| @Mapper 和 @MapperScan 区别? | @Mapper 单个标注,@MapperScan 批量扫描 |
| 如何配置多数据源? | 分别创建 DataSource、SqlSessionFactory、@MapperScan |
| 事务怎么管理? | @Transactional,Spring 管理事务 |
| SQL 日志怎么打印? | logging.level.com.xxx.mapper=DEBUG |
