spring boot 整合 mybatis 实现原理
类名作用自动配置类,整合 MyBatis创建 MyBatis 的注册 Mapper 接口扫描器实际执行 Mapper 接口扫描将 Mapper 接口封装为 Spring Bean线程安全的SqlSession,用于执行 SQL。
·
在 Spring Boot 中整合 MyBatis 是一个常见的场景,它通过自动配置和约定优于配置的方式简化了 MyBatis 的集成。
一、整体流程
- 引入依赖(如
mybatis-spring-boot-starter) - Spring Boot 自动加载
MyBatisAutoConfiguration - 创建数据源
DataSource - 构建
SqlSessionFactory - 注册
MapperScannerConfigurer扫描 Mapper 接口 - 注入
SqlSessionTemplate或Mapper到业务层使用
二、依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
三、核心类与方法
1. MyBatisAutoConfiguration
这是 MyBatis 在 Spring Boot 中的自动配置类,负责初始化关键组件。
类路径:
org.mybatis.spring.boot.autoconfigure.MyBatisAutoConfiguration
核心方法:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MyBatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MyBatisAutoConfiguration {
private final MyBatisProperties properties;
public MyBatisAutoConfiguration(MyBatisProperties properties) {
this.properties = properties;
}
// 创建 SqlSessionFactoryBean
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class); // 使用 Spring Boot 的 VFS 加载资源
factory.setConfigLocation(this.properties.resolveConfigLocation()); // mybatis.config-location
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); // type-handlers-package
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); // type-aliases-package
return factory.getObject(); // 构建 SqlSessionFactory
}
// 创建事务管理器
@Bean
@ConditionalOnMissingBean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// 注册 Mapper 扫描器
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage(this.properties.getMapperLocations()); // 配置 Mapper 接口包路径
return configurer;
}
}
2. SqlSessionFactoryBean
用于创建 SqlSessionFactory,是 MyBatis 和 Spring 集成的关键类。
类路径:
org.mybatis.spring.SqlSessionFactoryBean
核心方法:
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ResourcesLoadedEvent> {
private Resource configLocation; // mybatis-config.xml 文件位置
private String[] mapperLocations; // Mapper XML 文件路径
private DataSource dataSource; // 数据源
private Class<? extends VFS> vfs; // 虚拟文件系统
private String typeHandlersPackage; // 类型处理器包
private String typeAliasesPackage; // 别名包
// 初始化方法,在 afterPropertiesSet 中完成配置
@Override
public void afterPropertiesSet() throws Exception {
notNull(dataSource, "Property 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
org.apache.ibatis.session.Configuration configuration;
if (this.configuration != null) {
configuration = this.configuration;
} else if (this.configLocation != null) {
configuration = new ConfigurationBuilder().parse(this.configLocation); // 解析 mybatis-config.xml
} else {
configuration = new org.apache.ibatis.session.Configuration();
}
// 设置类型别名
if (StringUtils.hasText(typeAliasesPackage)) {
configuration.getTypeAliasRegistry().registerAliases(typeAliasesPackage);
}
// 设置类型处理器
if (StringUtils.hasText(typeHandlersPackage)) {
configuration.getTypeHandlerRegistry().register(typeHandlersPackage);
}
// 加载 Mapper XML 文件
if (mapperLocations != null) {
for (Resource mapperLocation : mapperLocations) {
if (mapperLocation.exists()) {
configuration.addMappers(mapperLocation); // 添加 Mapper 映射
}
}
}
// 创建 SqlSessionFactory
this.sqlSessionFactory = buildSqlSessionFactory(configuration);
}
// 构建 SqlSessionFactory
protected SqlSessionFactory buildSqlSessionFactory(org.apache.ibatis.session.Configuration configuration) {
return sqlSessionFactoryBuilder.build(configuration);
}
// 返回工厂创建的对象
@Override
public SqlSessionFactory getObject() throws Exception {
return getSqlSessionFactory();
}
}
3. MapperScannerConfigurer
扫描 Mapper 接口并注册为 Spring Bean。
类路径:
org.mybatis.spring.mapper.MapperScannerConfigurer
核心方法:
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ResourceLoaderAware {
private String basePackage; // Mapper 接口所在的包
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setAnnotationClass(Mapper.class); // 指定 @Mapper 注解
scanner.setMarkerInterface(Mapper.class); // 指定标记接口
scanner.registerFilters(); // 注册过滤器
scanner.doScan(basePackage); // 执行扫描
}
// 设置基础包路径
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
}
4. ClassPathMapperScanner
继承自 ClassPathBeanDefinitionScanner,用于扫描 Mapper 接口。
类路径:
org.mybatis.spring.mapper.ClassPathMapperScanner
核心方法:
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
super(registry, false); // 不使用默认的 Component 注解过滤器
}
@Override
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
for (BeanDefinitionHolder holder : beanDefinitions) {
GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
// 设置 MapperFactoryBean 作为 Bean 的工厂类
definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName());
definition.setBeanClassName(MapperFactoryBean.class.getName());
// 设置是否需要懒加载
definition.setLazyInit(lazyInitialization);
}
return beanDefinitions;
}
}
5. MapperFactoryBean
将每个 Mapper 接口包装为 Spring 管理的 Bean。
类路径:
org.mybatis.spring.mapper.MapperFactoryBean
核心方法:
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
private Class<T> mapperInterface; // Mapper 接口类型
@Override
public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface); // 获取 Mapper 实例
}
@Override
public Class<T> getObjectType() {
return this.mapperInterface;
}
@Override
public boolean isSingleton() {
return true;
}
public void setMapperInterface(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
}
6. SqlSessionTemplate
线程安全的 SqlSession,用于执行 SQL 操作。
类路径:
org.mybatis.spring.SqlSessionTemplate
核心方法:
public class SqlSessionTemplate implements SqlSession, DisposableBean {
private final SqlSessionFactory sqlSessionFactory; // 工厂
private final ExecutorType executorType; // 执行器类型
private final SqlSession sqlSessionProxy; // 代理对象
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
SqlSession.class.getClassLoader(),
new Class[]{SqlSession.class},
new SqlSessionInterceptor()); // 动态代理
}
// 获取 Mapper 接口的实例
@Override
public <T> T getMapper(Class<T> type) {
return getConfiguration().getMapper(type, this);
}
// 内部拦截器处理事务等逻辑
private class SqlSessionInterceptor implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final SqlSession sqlSession = getSqlSession(sqlSessionFactory, executorType);
try {
Object result = method.invoke(sqlSession, args); // 执行真实方法
if (!isSqlSessionTransactional(sqlSession, sqlSessionFactory)) {
sqlSession.commit(true); // 提交事务
}
return result;
} finally {
closeSqlSession(sqlSession, sqlSessionFactory);
}
}
}
}
四、总结
| 类名 | 作用 |
|---|---|
MyBatisAutoConfiguration |
自动配置类,整合 MyBatis |
SqlSessionFactoryBean |
创建 MyBatis 的 SqlSessionFactory |
MapperScannerConfigurer |
注册 Mapper 接口扫描器 |
ClassPathMapperScanner |
实际执行 Mapper 接口扫描 |
MapperFactoryBean |
将 Mapper 接口封装为 Spring Bean |
SqlSessionTemplate |
线程安全的 SqlSession,用于执行 SQL |
五、流程图
启动应用
│
├─ 引入 mybatis-spring-boot-starter
│
├─ Spring Boot 加载自动配置
│ └─ 加载 MyBatisAutoConfiguration
│ ├─ 创建 SqlSessionFactory
│ │ └─ 使用 SqlSessionFactoryBean 构建
│ ├─ 创建事务管理器
│ └─ 注册 MapperScannerConfigurer
│ └─ 扫描 Mapper 接口 -> MapperFactoryBean -> 注册为 Bean
│
└─ 使用时注入 Mapper 接口
└─ Spring 从容器中获取 MapperFactoryBean.getObject()
└─ 获取 SqlSessionTemplate.getMapper()
└─ MyBatis 创建动态代理对象执行 SQL
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)