mybatis-spring 是 MyBatis 官方团队 开发的一个桥接模块,其核心目标是:让 MyBatis 能够无缝集成到 Spring Framework 应用中,充分利用 Spring 的依赖注入(DI)、事务管理、生命周期管理等能力。
一、mybatis-spring 是谁开发的?
-
开发者:MyBatis 官方团队(原 iBATIS 团队演进而来)
-
GitHub 仓库:https://github.com/mybatis/spring
-
Maven 坐标 :
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> <!-- 最新版本请查 Maven Central --> </dependency>
💡 虽然由 MyBatis 社区维护,但它被广泛认可为 Spring 生态中集成 MyBatis 的标准方式 ,也被 Spring Boot 官方 starter(
mybatis-spring-boot-starter)所依赖。
二、mybatis-spring 主要做了什么?
它解决了 "如何让非 Spring 原生框架(MyBatis)在 Spring 容器中正确运行" 的问题。具体来说,它完成了以下关键工作:
1. 将 SqlSessionFactory 纳入 Spring 容器管理
MyBatis 的核心是 SqlSessionFactory,但它是 MyBatis 自己的对象,不是 Spring Bean。
✅ mybatis-spring 提供了:
org.mybatis.spring.SqlSessionFactoryBean
这是一个 Spring 的 FactoryBean<SqlSessionFactory> ,允许你在 Spring 配置中像声明普通 Bean 一样创建 SqlSessionFactory:
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
return factory.getObject(); // 返回真正的 SqlSessionFactory
}
这样,SqlSessionFactory 就成了 Spring 容器的一部分,可以被其他 Bean 注入或引用。
2. 自动为 Mapper 接口生成代理实现(并注册为 Spring Bean)
在纯 MyBatis 中,你需要手动调用:
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
但在 Spring 中,我们希望直接 @Autowired 使用:
@Service
public class UserService {
@Autowired
private UserMapper userMapper; // 直接注入!
}
✅ mybatis-spring 通过以下机制实现这一点:
(1)MapperFactoryBean
-
为单个 Mapper 接口创建代理对象,并注册为 Spring Bean。
-
示例(XML 配置时代常用):
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.example.UserMapper"/> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean>
(2)MapperScannerConfigurer(XML)或 @MapperScan(Java Config)
-
自动扫描包下所有接口,批量注册为 Spring Bean。
-
这就是你在 Spring Boot 中常用的:
@MapperScan("com.example.demo.mapper") @Configuration public class MyBatisConfig { ... } -
底层原理:利用 Spring 的
BeanDefinitionRegistryPostProcessor,在容器启动时动态注册MapperFactoryBean的定义。
✅ 最终效果:每个 Mapper 接口都对应一个 Spring Bean,可以直接注入使用。
3. 与 Spring 事务管理无缝集成
MyBatis 本身有自己的事务控制(SqlSession.commit() / rollback()),但这和 Spring 的声明式事务(@Transactional)冲突。
✅ mybatis-spring 提供了:
org.mybatis.spring.SqlSessionTemplate
- 这是一个 线程安全的、Spring 事务感知的
SqlSession代理 - 它会自动加入 Spring 的事务上下文:
- 如果当前有 Spring 事务,则复用同一个数据库连接
- 如果没有,则开启新连接并在方法结束时自动关闭
同时,你通常不需要直接使用 SqlSessionTemplate,因为 Mapper 代理内部已经使用它了。
🔄 效果:在
@Transactional方法中调用多个 Mapper,它们共享同一个数据库连接和事务!
4. 异常转换(Exception Translation)
MyBatis 抛出的是 PersistenceException 等,而 Spring 推荐使用统一的 DataAccessException 层级。
✅ mybatis-spring 自动将 MyBatis 异常转换为 Spring 的 DataAccessException 子类(如 DuplicateKeyException),便于统一处理。
三、架构图简示
+---------------------+
| Spring Container |
+----------+----------+
|
| 注入
+----------v----------+
| UserMapper (Proxy)|
+----------+----------+
| 调用
+----------v----------+
| SqlSessionTemplate | ←--- 绑定到 Spring 事务
+----------+----------+
|
+----------v----------+
| SqlSessionFactory |
+----------+----------+
|
+----------v----------+
| DataSource |
+---------------------+
四、总结:mybatis-spring 的核心价值
| 功能 | 解决的问题 |
|---|---|
SqlSessionFactoryBean |
让 SqlSessionFactory 成为 Spring Bean |
@MapperScan / MapperFactoryBean |
自动将 Mapper 接口注册为可注入的 Spring Bean |
SqlSessionTemplate |
使 MyBatis 会话参与 Spring 事务管理 |
| 异常转换 | 统一数据访问异常体系 |
| 生命周期管理 | 由 Spring 控制资源创建与销毁 |
一句话总结 :
mybatis-spring是 MyBatis 与 Spring 之间的"翻译官"和"粘合剂",让 MyBatis 能像原生 Spring 组件一样被管理和使用。
如果你使用 Spring Boot + MyBatis,底层正是通过 mybatis-spring 实现的集成。理解它,就理解了 MyBatis 在 Spring 中工作的本质。