Spring Boot 透過 mybatis-spring-boot-starter 實現 MyBatis 零配置整合。本文詳細介紹兩種整合方式,重點講解 Starter 方式的依賴、屬性配置、SQL 日誌調試、事務管理(含 @Transactional 失效坑點),助你快速構建穩健的數據訪問層。
SqlSessionFactory、MapperScannerConfigurer 等 Bean。靈活但樣板代碼多。mybatis-spring-boot-starter,配合 application.yml 自動裝配,約定優於配置。<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version> <!-- 根據 Spring Boot 版本選擇 -->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 推薦使用 Druid/HikariCP 連接池
type: com.zaxxer.hikari.HikariDataSource
mybatis:
type-aliases-package: com.example.domain.model # 實體類別名包
type-handlers-package: com.example.typehandler # 自定義 TypeHandler
mapper-locations: classpath:mapper/*.xml # XML 映射文件路徑
configuration:
map-underscore-to-camel-case: true # 下劃線轉駝峰
default-fetch-size: 100
default-statement-timeout: 30
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台輸出 SQL
觀察生成 SQL、參數綁定、執行結果,定位問題利器。
logging:
level:
com.example.mapper: DEBUG # 你的 Mapper 接口包路徑
輸出範例:
==> Preparing: insert into `user`(id, name, password) values(?, ?, ?)
==> Parameters: id123(String), jack(String), 123(String)
<== Updates: 1
==> Preparing: select * from `user` where id = ?
==> Parameters: id123(String)
<== Total: 1
Spring 管理事務,支援聲明式 @Transactional。
@Mapper
public interface UserMapper {
void createUser(User user);
User findUserById(@Param("id") String id);
}
@Component
@Transactional // 類上標註,所有 public 方法開啟事務
public class UserDao {
@Autowired UserMapper userMapper;
public List<String> createBatch() {
User u1 = new User("id1", "a", "pwd");
User u2 = new User("id1", "b", "pwd"); // 主鍵衝突
userMapper.createUser(u1);
userMapper.createUser(u2); // 拋異常,整體回滾
return List.of("id1");
}
}
@RestController
public class UserController {
@Autowired UserDao userDao;
@Autowired UserMapper userMapper;
@GetMapping("/user/create/batch")
public List<User> createBatch() {
try { userDao.createBatch(); } catch (Exception ignored) {}
return userMapper.loadAllUsers();
}
}
| 場景 | 原因 | 對策 |
|---|---|---|
| Controller 方法直標 @Transactional | Spring AOP 基於代理,Controller 非由容器管理的 Bean 內部調用 | 將事務邊界下沉到 Service/DAO 層 |
| 同類內部方法互調 | this.xxx() 繞過代理 | 注入自身 Bean、或改用編程式事務 (TransactionTemplate) |
| 私有/非 public 方法 | AOP 只攔截 public | 改為 public |
| 異常被捕獲未重拋 | 事務管理器感知不到異常 | catch 後 throw new RuntimeException(e) 或標註 rollbackFor |
Spring Boot + MyBatis Starter 讓整合變得極簡,核心在於:依賴正確、屬性對齊、日誌開啟、事務邊界清晰。避開 @Transactional 失效坑,配合 Druid 連接池與 SQL 輸出,即可構建生產級數據訪問層。