springboot动态切换数据源不重启(springboot 项目中多个数据源切换)

技术Springboot动态切换数据源怎么实现这篇文章主要介绍“Springboot动态切换数据源怎么实现”,在日常操作中,相信很多人在Springboot动态切换数据源怎么实现问题上存在疑惑,小编查阅了各式资料,整理出

这篇文章主要介绍"跳羚动态切换数据源怎么实现",在日常操作中,相信很多人在跳羚动态切换数据源怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"跳羚动态切换数据源怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前言

在跳羚项目中只需一句代码即可实现多个数据源之间的切换:

//切换sqlserver数据源:

datasourcetextholder。setdatabasetype(DataSourceEnum .SQLSERVER _ DATASOURCE

.

//切换关系型数据库数据源

datasourcetextholder。setdatabasetype(DataSourceEnum .MYSQL _ DATASOURCE

具体实现:

本实例基于回弹2.5版本实现。

1.配置数据源:

在配置文件中配置多个数据源的连接信息,用不同的前缀作为区别:

#sqlserver数据源1:前缀为:弹簧。数据源。SQL服务器

春天。数据源。SQL服务器。驱动程序类名称。微软。SQL服务器。JDBC。sqlserverdriver

春天。数据源。SQL服务器。JDBC-URL=JDBC : SQL server ://localhost :1433;数据库名=测试

春天。数据源。SQL服务器。用户名=sa

春天。数据源。SQL服务器。密码=sa

#mysql数据源1:前缀为:spring.datasource.mysql

春天。数据源。MySQL。驱动程序类名称。MySQL。JDBC。驾驶员

春天。数据源。MySQL。JDBC-URL=JDBC : MySQL ://localhost :3306/测试?useUnicode=真字符编码=UTF-8 usessl=假allowmultiquery=真

春天。数据源。MySQL。用户名=根

春天。数据源。MySQL。密码=根

# sqlLite数据源1:前缀为:spring.datasource.sqlite

春天。数据源。SQLite。驱动程序类名称=组织。SQLite。JDBC

春天。数据源。SQLite。JDBC-网址=JDBC :s qlite :d ://sqllite//test。

春天。数据源。SQLite。用户名=

春天。数据源。SQLite。密码=

#sqlserver数据源2:前缀为:弹簧。数据源。SQL server 2

春天。数据源。SQL server 2。驱动程序类名称。微软。SQL服务器。JDBC。SQL server驱动程序

春天。数据源。SQL server 2。JDBC-URL=JDBC : SQL server ://localhost;DatabaseName=test1

春天。数据源。SQL server 2。用户名=sa

春天。数据源。SQL server 2。密码=sa

#配置数据库连接池信息

春天。数据源。回力。最大池大小=32

春天。数据源。回力。最小怠速=162 .新建枚举类数据来源,有几个数据源对应设置几个枚举类。

publicenumDataSourceEnum {

MYSQL _ DATASOURCE,

SQLSERVER _ DATASOURCE,

SQLSERVER2 _ DATASOURCE,

SQLLITE _ DATASOURCE

}3.新建数据库切换工具类数据源文本持有者,这里通过ThreadLocal类型的变量来存储当前数据源枚举类,同时能够保证线程安全。

rush:java;">public class DataSourceContextHolder {

    /**
     * 通过ThreadLocal保证线程安全
     */
    private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<>();

    /**
     * 设置数据源变量
     * @param dataSourceEnum 数据源变量
     */
    public static void setDataBaseType(DataSourceEnum dataSourceEnum) {
        System.out.println("修改数据源为:" + dataSourceEnum);
        contextHolder.set(dataSourceEnum);
    }

    /**
     * 获取数据源变量
     * @return 数据源变量
     */
    public static DataSourceEnum getDataBaseType() {
        DataSourceEnum dataSourceEnum = contextHolder.get() == null ? DataSourceEnum.MYSQL_DATASOURCE : contextHolder.get();
        System.out.println("当前数据源的类型为:" + dataSourceEnum);
        return dataSourceEnum;
    }

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

4.新建DynamicDataSource类继承AbstractRoutingDataSource类,并实现determineCurrentLookupKey方法,该方法是指定当前默认数据源的方法。

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataBaseType();
    }
}

这个类看似内容不多,但其实继承了AbstractRoutingDataSource类是实现动态切换数据源的关键。

5.新建DataSourceConfig类用来创建bean的实例,其中包括各数据源的DataSource实例,DynamicDataSource实例以及跟Mybatis相关的SqlSessionFactory或Spring的JdbcTemplate实例。

@Configuration
public class DataSourceConfig {
    @Bean(name = "sqlserverDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.sqlserver")
    public DataSource getDateSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "sqlserver2DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.sqlserver2")
    public DataSource getDateSource11() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mysqlDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource getDateSource2() {
        return DataSourceBuilder.create().build();
    }


    @Bean(name = "sqlLiteDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.sqlite")
    public DataSource getDateSource3() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    public DynamicDataSource DataSource(@Qualifier("sqlserverDataSource") DataSource sqlserverDataSource,
                                        @Qualifier("sqlserver2DataSource") DataSource sqlserver2DataSource,
                                        @Qualifier("mysqlDataSource") DataSource mysqlDataSource,
                                        @Qualifier("sqlLiteDataSource") DataSource sqlLiteDataSource) {
        //配置多数据源
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put(DataSourceEnum.SQLSERVER_DATASOURCE, sqlserverDataSource);
        targetDataSource.put(DataSourceEnum.MYSQL_DATASOURCE, mysqlDataSource);
        targetDataSource.put(DataSourceEnum.SQLLITE_DATASOURCE, sqlLiteDataSource);
        targetDataSource.put(DataSourceEnum.SQLSERVER2_DATASOURCE, sqlserver2DataSource);
        DynamicDataSource dataSource = new DynamicDataSource();
        //多数据源
        dataSource.setTargetDataSources(targetDataSource);
        //默认数据源
        dataSource.setDefaultTargetDataSource(sqlserverDataSource);
        return dataSource;
    }
    @Bean(name = "SqlSessionFactory")
    public SqlSessionFactory test1SqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dynamicDataSource);
        return bean.getObject();
    }

    @Bean(name = "JdbcTemplate")
    public JdbcTemplate test1JdbcTemplate(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) {
        return new JdbcTemplate(dynamicDataSource);
    }
}

这样就把我们切换数据库锁需要的bean全部交给spring容器中了,使用时直接通过DataSourceContextHolder.setDataBaseType(DataSourceEnum dataSourceEnum);这个方法指定数据源对应的枚举类即可。

原理分析:

Springboot动态切换数据源怎么实现

其实我们新建数据库连接的时候也是通过DataSource来获取连接的,这里的AbstractRoutingDataSource也是通过了DataSource中的getConnection方法来获取连接的。

Springboot动态切换数据源怎么实现

这个类里维护了两个Map来存储数据库连接信息:

@Nullable
private Map<Object, Object> targetDataSources; 

@Nullable
private Object defaultTargetDataSource;

private boolean lenientFallback = true;

private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();

@Nullable
private Map<Object, DataSource> resolvedDataSources;

@Nullable
private DataSource resolvedDefaultDataSource;

下面对上面的几个属性进行说明:

其中第一个targetDataSources是一个Map对象,在我们上面第五步创建DynamicDataSource实例的时候将多个数据源的DataSource类,放入到这个Map中去,这里的Key是枚举类,values就是DataSource类。

Springboot动态切换数据源怎么实现

第二个defaultTargetDataSource是默认的数据源,就是DynamicDataSource中唯一重写的方法来给这个对象赋值的。

Springboot动态切换数据源怎么实现

第三个lenientFallback是一个标识,是当指定数据源不存在的时候是否采用默认数据源,默认是true,设置为false之后如果找不到指定数据源将会返回null.

Springboot动态切换数据源怎么实现

第四个dataSourceLookup是用来解析指定的数据源对象为DataSource实例的。默认是JndiDataSourceLookup实例,继承自DataSourceLookup接口。

第五个resolvedDataSources也是一个Map对象,这里是存放指定数据源解析后的DataSource对象。

Springboot动态切换数据源怎么实现

第六个resolvedDefaultDataSource是默认的解析后的DataSource数据源对象上面的getConnection方法就是从这个变量中拿到DataSource实例并获取连接的。

Springboot动态切换数据源怎么实现

到此,关于“Springboot动态切换数据源怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/149064.html

(0)

相关推荐

  • RHEL5.1创建本地及FTP的yum源是怎样的

    技术RHEL5.1创建本地及FTP的yum源是怎样的本篇文章给大家分享的是有关RHEL5.1创建本地及FTP的yum源是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小

    攻略 2021年11月17日
  • C#调用C++的坑分析

    技术C#调用C++的坑分析这篇文章主要介绍“C#调用C++的坑分析”,在日常操作中,相信很多人在C#调用C++的坑分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#调用C++的坑分析”

    攻略 2021年11月30日
  • 鱼子酱是什么,请问鱼子酱是道什么菜~

    技术鱼子酱是什么,请问鱼子酱是道什么菜~1. 直接食用:鱼子酱直接送入口中,先用牙齿将鱼卵轻轻咬破,耳中欣赏“啵鱼子酱是什么、啵”的声音,再用舌头仔细品味,然后才吞下去。2. 在苏打饼干上涂上少许鱼子酱,细细地品味它的滋

    生活 2021年10月28日
  • Python脚本程序与Perl怎么进行比较

    技术Python脚本程序与Perl怎么进行比较Python脚本程序与Perl怎么进行比较,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Python脚本程序在

    攻略 2021年10月28日
  • jmeter如何测试加密接口(jmeter接口测试要考虑什么)

    技术jmeter接口测试流程是怎样的这篇文章主要介绍“jmeter接口测试流程是怎样的”,在日常操作中,相信很多人在jmeter接口测试流程是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家

    攻略 2021年12月17日
  • 基维百科,维基百科新规带来哪些改变

    技术基维百科,维基百科新规带来哪些改变为确保其平台的安全以及对抗各种骚扰行为,维基百科近日宣布正在实施新的行为准则基维百科。部分成员,尤其是女性和LGBTQ社区成员,抱怨平台上经常遭到会员编辑的“有毒行为”言语。该网站主

    生活 2021年10月31日