数据源,连接池,mybatis和事务
启动时
1.配置DataSource配置文件
2.DataSourceBuilder指定连接池,返回由连接池实现的DataSource,每个数据源都有一个连接池,连接池初始化几个连接
3.如果需要多数据源,这个时候需要DynamicDataSource,添加多有数据源,再返回一个由DynamicDataSource实现的DataSource
3.PlatformTransactionManager事务管理器初始化,拿到的是由DynamicDataSource实现的数据源
4.SqlSessionFactoryBean初始化,拿到的是由DynamicDataSource实现的数据源
运行时
1.aop拦截到方法开启了事务,事务管理器通过注入的DataSource的getConnection拿到连接,开启事务
2.getConnection先经过DynamicDataSource切换数据源,拿到连接池实现的数据源,再由连接池返回真正的Connection连接
3.拿到连接后开启事务
4.执行sql时,SqlSessionFactory通过注入的DataSource的getConnection拿到连接
5.和事务一样经过DynamicDataSource再拿到连接池实现的数据源,返回真正的Connection连接
6.执行sql并返回
7.事务管理器提交事务
特别说明
1.数据源只是一个空接口,只有一个getConnection方法
2.如果没有多数据源,那事务管理器和SqlSessionFactory拿到的就直接是连接池实现的数据源
一个配置例子
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@MapperScan("com.mapper.**") // 扫描DAO
public class MybatisConfig {
@Bean("master")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource master() {
return DataSourceBuilder.create().build();
}
@Bean("slave")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slave() {
return DataSourceBuilder.create().build();
}
@Bean("dynamicDataSource")
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put("master", master());
dataSourceMap.put("slave", slave());
// 将 master 数据源作为默认指定的数据源
dynamicDataSource.setDefaultDataSource(master());
// 将 master 和 slave 数据源作为指定的数据源
dynamicDataSource.setDataSources(dataSourceMap);
return dynamicDataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
// 配置数据源,此处配置为关键配置,如果没有将 dynamicDataSource作为数据源则不能实现切换
sessionFactory.setDataSource(dynamicDataSource());
sessionFactory.setTypeAliasesPackage("com.entity.**"); // 扫描Model
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactory.setMapperLocations(resolver.getResources("classpath*:com.mapper/*.xml")); // 扫描映射文件
return sessionFactory;
}
@Bean
public PlatformTransactionManager transactionManager() {
// 配置事务管理, 使用事务时在方法头部添加@Transactional注解即可
return new DataSourceTransactionManager(dynamicDataSource());
}
}