iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Springboot动态切换数据源怎么实现
  • 945
分享到

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

2023-06-25 21:06:30 945人浏览 安东尼
摘要

这篇文章主要介绍“SpringBoot动态切换数据源怎么实现”,在日常操作中,相信很多人在springboot动态切换数据源怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Springboot动态切换数

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

前言

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

// 切换sqlserver数据源:DataSourceContextHolder.setDataBaseType(DataSourceEnum.SQLSERVER_DATASOURCE);......// 切换mysql数据源    DataSourceContextHolder.setDataBaseType(DataSourceEnum.Mysql_DATASOURCE);

具体实现:

本实例基于springboot2.5+版本实现。

配置数据源:

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

# sqlserver数据源1:前缀为:spring.datasource.sqlserverspring.datasource.sqlserver.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.datasource.sqlserver.jdbc-url=jdbc:sqlserver://localhost:1433;DatabaseName=testspring.datasource.sqlserver.username=saspring.datasource.sqlserver.passWord=sa# mysql数据源1:前缀为:spring.datasource.mysqlspring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driverspring.datasource.mysql.jdbc-url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=truespring.datasource.mysql.username=rootspring.datasource.mysql.password=root# sqlLite数据源1:前缀为:spring.datasource.sqlitespring.datasource.sqlite.driver-class-name=org.sqlite.JDBCspring.datasource.sqlite.jdbc-url=jdbc:sqlite:D://sqllite//test.dbspring.datasource.sqlite.username=spring.datasource.sqlite.password=# sqlserver数据源2:前缀为:spring.datasource.sqlserver2spring.datasource.sqlserver2.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.datasource.sqlserver2.jdbc-url=jdbc:sqlserver://localhost;DatabaseName=test1spring.datasource.sqlserver2.username=saspring.datasource.sqlserver2.password=sa# 配置数据库连接池信息spring.datasource.hikari.maximum-pool-size=32spring.datasource.hikari.minimum-idle=16

新建枚举类DataSourceEnum,有几个数据源对应设置几个枚举类。

public enum DataSourceEnum {    MYSQL_DATASOURCE,    SQLSERVER_DATASOURCE,    SQLSERVER2_DATASOURCE,    SQLLITE_DATASOURCE}

新建数据库切换工具类DataSourceContextHolder,这里通过ThreadLocal类型的变量来存储当前数据源枚举类,同时能够保证线程安全

public class DataSourceContextHolder {        private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<>();        public static void setDataBaseType(DataSourceEnum dataSourceEnum) {        System.out.println("修改数据源为:" + dataSourceEnum);        contextHolder.set(dataSourceEnum);    }        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();    }

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

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

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

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

@Configurationpublic 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来存储数据库连接信息:

@Nullableprivate Map<Object, Object> targetDataSources; @Nullableprivate Object defaultTargetDataSource;private boolean lenientFallback = true;private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();@Nullableprivate Map<Object, DataSource> resolvedDataSources;@Nullableprivate 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动态切换数据源怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Springboot动态切换数据源怎么实现

本文链接: https://www.lsjlt.com/news/306410.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作