一、快速集成:单数据源配置
1. 添加 Maven 依赖
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version> <!-- 注意:适配 Spring Boot 3.x -->
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
🔔 注意:
- Spring Boot 3.x 需使用
mybatis-spring-boot-starter3.x+;- 若用 Spring Boot 2.x,请降级到 2.3.x。
2. 配置 application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml # XML 文件位置
type-aliases-package: com.charles.entity # 实体类别名包
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印 SQL
3. 编写实体类 & Mapper
// User.java
package com.charles.entity;
public class User {
private Integer id;
private String username;
// getter / setter
}
// UserMapper.java
package com.charles.mapper;
import com.charles.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper // 👈 关键注解!
public interface UserMapper {
User selectById(Integer id);
void insert(User user);
}
✅ 两种注册 Mapper 方式(二选一):
- 在每个 Mapper 接口上加
@Mapper;- 在启动类上加
@MapperScan("com.charles.mapper")(推荐,避免重复注解)。
4. Service 层 + 事务控制
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// ✅ 自动开启事务(默认 REQUIRED)
@Transactional
public void createUser(User user) {
userMapper.insert(user);
// 模拟异常:若此处出错,insert 会回滚
if (user.getUsername().contains("error")) {
throw new RuntimeException("模拟异常");
}
}
public User getUser(Integer id) {
return userMapper.selectById(id); // 只读,无需事务
}
}
💡 Spring 的
@Transactional与 MyBatis 完美协作,无需手动 commit/rollback!
二、进阶:配置多数据源(Multi-DataSource)
场景说明
- 主库(master):写操作(订单、用户注册)
- 从库(slave):读操作(报表、查询)
步骤 1:添加两个数据源配置
spring:
datasource:
master:
jdbc-url: jdbc:mysql://localhost:3306/master_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
jdbc-url: jdbc:mysql://localhost:3306/slave_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
⚠️ 注意:Spring Boot 2.7+ 使用
jdbc-url而非url(HikariCP 要求)。
步骤 2:创建主从数据源配置类
// MasterDataSourceConfig.java
@Configuration
@MapperScan(
basePackages = "com.charles.mapper.master",
sqlSessionFactoryRef = "masterSqlSessionFactory"
)
public class MasterDataSourceConfig {
@Bean
@Primary // 主数据源
@ConfigurationProperties("spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource ds)
throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryFactoryBean();
factory.setDataSource(ds);
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/master/*.xml"));
return factory.getObject();
}
@Bean
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(
@Qualifier("masterSqlSessionFactory") SqlSessionFactory sf) {
return new SqlSessionTemplate(sf);
}
}
// SlaveDataSourceConfig.java(类似,去掉 @Primary,包路径改为 slave)
步骤 3:按用途划分 Mapper 包
src/main/java
└── com.charles.mapper
├── master
│ └── UserWriteMapper.java // 写操作
└── slave
└── UserReadMapper.java // 读操作
✅ 这样,写操作走主库,读操作走从库,实现读写分离!
三、常见问题 & 最佳实践
❓ Q1:启动报错 "No qualifying bean of type 'XXXMapper'"?
- 原因:未正确扫描 Mapper 接口;
- 解决:检查
@MapperScan包路径是否包含 Mapper 所在包。
❓ Q2:事务不生效?
- 原因1:方法非 public;
- 原因2:自调用(this.method());
- 原因3:异常被捕获未抛出;
- ✅ 解决:确保
@Transactional方法被外部调用,且抛出 RuntimeException。
✅ 最佳实践
- 使用
@MapperScan统一管理,避免每个接口加@Mapper; - 多数据源时,严格分离读写 Mapper 包;
- 生产环境关闭
log-impl,改用日志框架(如 Logback)记录 SQL; - 结合 Druid 或 HikariCP 监控连接池状态。
四、扩展:整合 PageHelper 分页插件
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
使用:
public List<User> getUsers(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
return userMapper.selectAll(); // 自动分页
}
🌟 无需修改 SQL,一行代码实现物理分页!
五、总结
| 能力 | Spring Boot + MyBatis 实现方式 |
|---|---|
| 单数据源 | mybatis-spring-boot-starter + application.yml |
| 事务管理 | @Transactional(由 Spring 管理) |
| 多数据源 | 多个 DataSource + @MapperScan 分包 |
| 分页 | PageHelper Starter |
| SQL 日志 | mybatis.configuration.log-impl |
✨ 核心优势 :
"零 XML 配置、自动事务、无缝整合、生产就绪!"