数据源,连接池,mybatis和事务

发布时间 2023-08-10 16:53:53作者: 猥琐熊花子酱

启动时

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());
    }
}