mybatis-spring 浅析

mybatis-springMyBatis 官方团队 开发的一个桥接模块,其核心目标是:让 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 中工作的本质。

相关推荐
zhougl99619 分钟前
Java 枚举类(enum)详解
java·开发语言·python
想七想八不如1140821 分钟前
2019机试真题
java·华为od·华为
恋爱绝缘体123 分钟前
Java语言提供了八种基本类型。六种数字类型【函数基数噶】
java·python·算法
MX_93591 小时前
使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描
java·后端·spring
弹简特1 小时前
【JavaEE05-后端部分】使用idea社区版从零开始创建第一个 SpringBoot 程序
java·spring boot·后端
1104.北光c°1 小时前
【黑马点评项目笔记 | 登录篇】Redis实现共享Session登录
java·开发语言·数据库·redis·笔记·spring·java-ee
爬山算法1 小时前
Hibernate(81)如何在数据同步中使用Hibernate?
java·后端·hibernate
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于javaweb的音乐节管理系统为例,包含答辩的问题和答案
java·eclipse
启山智软1 小时前
供应链商城核心功能模块清单
java·前端·开源
是萧萧吖1 小时前
每日一练——有效的括号
java·开发语言·javascript