springboot 2.1.4 mybatis多数源配置

第一步配置数据库连接

在这里插入图片描述
首先配置在application.properties问件配置数据库连接,当前springboo版本默认集成了hikari连接池,所以不用在pom里面引入依赖。

第二步配置sqlSessionFactory

@Configuration
@MapperScan(basePackages = "com.ppzdz.datasource.mapper", sqlSessionFactoryRef = "SqlSessionFactory")
public class DataSourceConfig {
    @Primary
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource getDateSource1() {
        HikariDataSource build = (HikariDataSource) DataSourceBuilder.create().build();
        build.setMaximumPoolSize(100);
        build.setConnectionTimeout(5000);
        return build;
    }

    @Bean(name = "slave1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave1")
    public DataSource getDateSource2() {
        HikariDataSource build = (HikariDataSource)DataSourceBuilder.create().build();
        build.setConnectionTimeout(5000);
        build.setIdleTimeout(5000);
        return build;
    }

    @Bean(name = "slave2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave2")
    public DataSource getDateSource3() {
        HikariDataSource build = (HikariDataSource)DataSourceBuilder.create().build();
        build.setConnectionTimeout(5000);
        build.setIdleTimeout(5000);
        return build;
    }

    @Bean(name = "dynamicDataSource")
    public DynamicDataSource DataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                        @Qualifier("slave1DataSource") DataSource slave1DataSource,
                                        @Qualifier("slave2DataSource") DataSource slave2DataSource) {
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put(DataSourceType.DataBaseType.MASTER, masterDataSource);
        targetDataSource.put(DataSourceType.DataBaseType.SLAVE1, slave1DataSource);
        targetDataSource.put(DataSourceType.DataBaseType.SLAVE2, slave2DataSource);
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSource);
        dataSource.setDefaultTargetDataSource(masterDataSource);
        return dataSource;
    }

    @Bean(name = "SqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dynamicDataSource);
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
        return bean.getObject();
    }

}
  1. @Configuration用于定义配置类,可替换xml配置文件

  2. @MapperScan扫描mybatis的mapper(dao)层的接口

  3. @Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

  4. @Primary可以理解为默认优先选择,上面为默认数据源的配置

  5. @ConfigurationProperties它可以把同类的配置信息自动封装成实体类,这里就是application.properties里的数据库连接自动封装

dataSource.setDefaultTargetDataSource(masterDataSource);默认数据源。不要忘了
是不是DynamicDataSource 有问题??,好像没有这个包??哈哈

第三步动态实现数据切换

请看图

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        DataSourceType.DataBaseType dataBaseType = DataSourceType.getDataBaseType();
        return dataBaseType;
    }

}

DynamicDataSource 这个类是自己定义的,重写了determineCurrentLookupKey()方法,AbstractRoutingDataSource

  • 多数据源的动态切换,在程序运行时,把数据源数据源动态织入到程序中,灵活的进行数据源切换。
  • 基于多数据源的动态切换,我们可以实现读写分离,这么做缺点也很明显,无法动态的增加数据源。

总之这个呢是切换数据源用的,详细信息大家可以看下源码。

编写AbstractRoutingDataSource的实现类,DataSourceType 就是提供给我们动态选择数据源的数据的信息,这里编写一个根据当前线程来选择数据源,然后通过AOP拦截特定的注解,设置当前的数据源信息。

public class DataSourceType {

    public enum DataBaseType {
        MASTER ,SLAVE1,SLAVE2
    }

    // 使用ThreadLocal保证线程安全
    private static final ThreadLocal<DataBaseType> TYPE = new ThreadLocal<DataBaseType>();

    // 往当前线程里设置数据源类型
    public static void setDataBaseType(DataBaseType dataBaseType) {
        if (dataBaseType == null) {
            throw new NullPointerException();
        }
        System.err.println("[将当前数据源改为]:" + dataBaseType);
        TYPE.set(dataBaseType);
    }

    // 获取数据源类型
    public static DataBaseType getDataBaseType() {
        DataBaseType dataBaseType = TYPE.get() == null ? DataBaseType.MASTER : TYPE.get();
        System.err.println("[获取当前数据源的类型为]:" + dataBaseType);
        return dataBaseType;
    }

    // 清空数据类型
    public static void clearDataBaseType() {
        TYPE.remove();
    }

}

最后一步

  • 基于aop动态切换
@Aspect
@Component
public class DataSourceAop {
	@Before("execution(* com.ppzdz.datasource.service..*.master*(..))")
	public void setDataSource3Master() {
		System.err.println("Master业务");
		DataSourceType.setDataBaseType(DataBaseType.MASTER);
	}
	
	@Before("execution(* com.ppzdz.datasource.service..*.slave1*(..))")
	public void setDataSource3Slave1() {
		System.err.println("Slave1业务");
		DataSourceType.setDataBaseType(DataBaseType.SLAVE1);
	}

	@Before("execution(* com.ppzdz.datasource.service..*.slave2*(..))")
	public void setDataSource3Slave2() {
		System.err.println("Slave2业务");
		DataSourceType.setDataBaseType(DataBaseType.SLAVE2);
	}
}

在这里插入图片描述

注意这是监听业务层的方法调用,在调用前注入数据源,方法名是否含有slave2、slave1。。。。如果都没有默认注入默认数据源。
然后,大功告成。如还有问题,发送邮件到320264603@qq.com。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值