MyBatis 与 Spring 集成原理 的深入剖析

下面是 MyBatis 与 Spring 集成原理 的深入剖析,涵盖集成方式、核心组件、源码机制以及如何实现无缝协作。MyBatis 本身是独立的持久层框架,通过与 Spring 集成,实现了 依赖注入、事务管理、Mapper 自动注册 等企业级能力。


🌐 一、MyBatis 与 Spring 集成的目标

功能原生 MyBatis集成 Spring 后
SqlSession 管理手动创建/关闭自动管理(SqlSessionTemplate
Mapper 使用sqlSession.getMapper()注入 Mapper 接口(@Autowired
事务管理手动提交/回滚与 Spring 事务同步(@Transactional
配置方式mybatis-config.xml + 手动构建Spring Bean 配置或 @Configuration
生命周期管理开发者负责由 Spring 容器管理

✅ 集成后:开发者不再直接操作 SqlSessionFactorySqlSession,而是像使用 Service 一样使用 Mapper。


🧩 二、集成方式(常用两种)

方式 1:使用 mybatis-spring 桥接包(推荐)

引入依赖:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>3.0.3</version>
</dependency>

Spring 配置(Java Config):

@Configuration
@MapperScan("com.example.mapper")  // 自动扫描 Mapper 接口
public class MyBatisConfig {

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource(); // 或 Druid、C3P0 等
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setMapperLocations(new ClassPathResource("mapper/*.xml"));
        return factoryBean.getObject();
    }

    // 可省略:SqlSessionTemplate 和 Mapper 自动注册
}

🔧 三、核心集成组件与原理

1. SqlSessionFactoryBean —— 创建 SqlSessionFactory

  • 实现 FactoryBean<SqlSessionFactory>,Spring 调用 getObject() 返回 SqlSessionFactory
  • 内部封装了原生 MyBatis 的 XMLConfigBuilderXMLMapperBuilder,完成配置解析。

📌 相当于把 new SqlSessionFactoryBuilder().build(inputStream) 这一步交给 Spring 管理。


2. MapperScannerConfigurer@MapperScan —— 自动注册 Mapper

  • Spring 启动时扫描指定包下的所有 Mapper 接口
  • 为每个接口生成一个 MapperFactoryBean 或直接注册代理对象。
  • 最终将 Mapper 代理注入到 IOC 容器中,支持 @Autowired
@Autowired
private UserMapper userMapper; // 实际是 JDK 动态代理对象
原理流程:
@ComponentScan
     ↓
@MapperScan → MapperScannerRegistrar → ImportBeanDefinitionRegistrar
     ↓
注册 Mapper 接口为 BeanDefinition(类型为 MapperFactoryBean)
     ↓
Spring 实例化时调用 MapperFactoryBean.getObject() → 获取代理对象

3. SqlSessionTemplate —— 线程安全的 SqlSession

  • 原生 SqlSession非线程安全的,不能放入 Spring 容器作为单例。
  • SqlSessionTemplate 是线程安全的,是 SqlSession 的代理类,内部通过 ThreadLocal 获取当前事务绑定的 SqlSession
核心特性:
  • 使用 Proxy 代理所有方法调用。
  • 与 Spring 的事务管理器(DataSourceTransactionManager)协同工作。
  • 自动从 TransactionSynchronizationManager 获取当前事务的 SqlSession

✅ 保证:同一个事务中,多次调用 getMapper() 返回的是同一个 SqlSession


4. SqlSessionUtils —— 与 Spring 事务集成的工具类

  • 在执行 sqlSession.select/update/insert/delete 前,调用 SqlSessionUtils.getSqlSession()
  • 该方法会:
    • 检查当前是否有事务绑定的 SqlSession
    • 若有,复用;若无,创建新的并注册到事务同步器。
  • 提交事务时,Spring 会回调 SqlSessionUtils.closeSqlSession()

5. 事务集成:DataSourceTransactionManager + SqlSession

当使用 @Transactional 时:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional
    public void saveUser() {
        userMapper.insert(new User("Alice"));
        userMapper.updateStatus(1); // 同一个 SqlSession
    }
}
事务流程:
@Transactional 开启
     ↓
TransactionManager 触发 doBegin()
     ↓
绑定 DataSource 和 Connection 到 ThreadLocal
     ↓
SqlSessionTemplate 检测到事务,复用该 Connection
     ↓
所有 Mapper 调用共享同一个 SqlSession 和 Connection
     ↓
@Transactional 结束 → 提交或回滚

📈 四、集成架构图(Mermaid)

graph TD
    A[Spring IOC 容器] --> B[SqlSessionFactoryBean]
    A --> C[MapperScannerConfigurer]
    A --> D[DataSourceTransactionManager]

    B --> E[SqlSessionFactory]
    E --> F[SqlSessionTemplate]
    F --> G[SqlSession (ThreadLocal)]

    C --> H[Mapper 接口]
    H --> I[MapperProxy 动态代理]
    I --> F

    D --> G
    G --> J[(Database)]

    subgraph "Spring 管理"
        A; B; C; D; F
    end

    subgraph "MyBatis 核心"
        E; I; G
    end

🔍 五、关键源码入口(可调试点)

类名作用
SqlSessionFactoryBean.java构建 SqlSessionFactory
MapperScannerRegistrar.java处理 @MapperScan 注解
MapperFactoryBean<T>为每个 Mapper 接口创建代理对象
SqlSessionTemplate.java线程安全的 SqlSession 代理
SqlSessionUtils.java与 Spring 事务集成的核心工具
MyBatisAutoConfiguration.java(Spring Boot)自动配置类

✅ 六、Spring Boot 中的自动配置(简化版)

在 Spring Boot 中,只需引入:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

自动配置生效:

  • 自动创建 SqlSessionFactory
  • 自动扫描 @Mapper 或指定包
  • 自动配置 SqlSessionTemplate
  • 支持 @MapperScan@Mapper 注解

配置文件 application.yml

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.entity

🧠 七、常见问题与最佳实践

问题解决方案
Invalid bound statement (not found)检查 Mapper 接口与 XML 的 namespace 和 id 是否匹配
事务不生效确保使用 @Transactional 在 Service 层,且类被 Spring 管理
一级缓存跨事务共享不会,因为 SqlSession 在事务结束后关闭
多数据源支持使用 AbstractRoutingDataSource + @DS 切换数据源

✅ 总结:MyBatis 与 Spring 集成的本质

MyBatis + Spring = SQL 控制力 + 容器管理 + 事务统一

核心机制说明
Bean 化SqlSessionFactoryMapper 都作为 Spring Bean 管理
代理注入Mapper 接口通过动态代理自动注入 IOC 容器
事务同步借助 SqlSessionTemplateTransactionSynchronization 实现事务一致性
开箱即用Spring Boot 更是做到“零配置”集成
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值