SpringBoot动态切换数据库

标签: 无 分类: 未分类 创建时间:2020-09-15 02:45:09 更新时间:2024-12-04 11:29:35

我也写了几篇关于springboot多数据源的问题,多数据源并不是动态数据源,多数据源其实也就是静态的数据源,主要还是不同的方法调用不同的DAO层,但是今天我要做到的就是根据前端发送的参数不同,实现请求不同数据库中内容,并返回,也就是动态的切换数据源的问题。

还有一点要实现的就是,不能通过配置文件的方式进行数据源的添加和删除,而要通过数据库的方式进行数据源的添加和删除。根据参考文章Springboot 从数据库读取数据库配置信息,动态切换多数据源 最详细实战教程 (这篇文章的需求跟我的很像,也是从数据库获取数据库信息,然后进行动态切换,我根据这篇文章,差不多可以成功了。),基本上实现了数据源的动态切换,我这里只是摘录相关的关键点,即我在操作时遇到的一些问题。

1.创建数据库

主要包括DataSource数据,以及其他数据库

2.添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<!--Mybatis Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!--sql server-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.1.0.jre8-preview</version>
</dependency>

3.配置主数据源

4.创建DataSource类

这个类的作用就是创建数据库连接信息

5.创建DruidDBConfig.java

配置默认的数据源,配置Druid数据库连接池,配置sql工厂加载mybatis的文件,扫描实体类等

6.手动切换数据源的 DBContextHolder.java

7.DynamicDataSource.java

手动加载默认数据源、创建数据源连接、检查数据源连接、删除数据源连接等

8.DataSourceMapper.java、DBChangeService.java以及DBChangeServiceImpl.java类

9.改造DruidDBConfig

以为我用的是mybatis plus,所以在返回SqlSessionFactory时,不能返回默认的SqlSessionFactory,需要返回MyBatisSqlSessionFactory,所以需要改造如下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Primary
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dynamicDataSource());
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
// 设置驼峰转换为下划线
configuration.setMapUnderscoreToCamelCase(false);

GlobalConfig globalConfig=new GlobalConfig();

GlobalConfig.DbConfig dbConfig=new GlobalConfig.DbConfig();
dbConfig.setTableUnderline(false); // 数据表名加下划线



globalConfig.setDbConfig(dbConfig);
configuration.setGlobalConfig(globalConfig);


sqlSessionFactory.setGlobalConfig(globalConfig);
sqlSessionFactory.setConfiguration(configuration);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/*.xml"));
return sqlSessionFactory.getObject();
}
参考文章:
1.SpringBoot + Mybatis配合AOP和注解实现动态数据源切换配置 (这篇文章中使用了AOP进行了动态数据源的切换,不需要结合注解进行)
2.SpringBoot 自定义+动态切换数据源 (这篇文章还讲了如何通过AOP+注解的方式进行动态数据源的切换)
3.Springboot 从数据库读取数据库配置信息,动态切换多数据源 最详细实战教程 (这篇文章的需求跟我的很像,也是从数据库获取数据库信息,然后进行动态切换,我根据这篇文章,差不多可以成功了。)
4.Spring Boot 动态数据源(多数据源自动切换) (这篇也是使用注解的方式进行动态数据源的切换)
5.springboot实现动态数据库切换 (这个主要讲了如何编写注解,以及使用AOP)

1.select 1 from dual

验证数据库的有效性,常用的语句如下:

  • hsqldb - select 1 from INFORMATION_SCHEMA.SYSTEM_USERS
  • Oracle - select 1 from dual
  • DB2 - select 1 from sysibm.sysdummy1
  • mysql - select 1
  • microsoft SQL Server - select 1 (tested on SQL-Server 9.0, 10.5 [2008])
  • postgresql - select 1
  • ingres - select 1
  • derby - values 1
  • H2 - select 1
  • Firebird - select 1 from rdb$database

问题

1.Cannot resolve symbol ‘RelaxedDataBinder’

在使用Druid配置多数据源的时候,报这个错误。因为我的spring-boot-starter-parent版本是2.3.2.RELEASE,所以我尝试了将druid依赖,换成了druid-spring-boot-starter依赖,但是还是不行

1
2
3
4
5
6
7
8
9
10
11
12
 <!-- <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.23</version>
</dependency> -->

<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>

我还尝试添加了druid-spring-boot2-starter,还是不起作用。

1
2
3
4
5
<dependency>
<groupId>com.github.drtrang</groupId>
<artifactId>druid-spring-boot2-starter</artifactId>
<version>1.1.10.2</version>
</dependency>
参考文章:
1.Spring boot 2.0 配置报错java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyRes (这个方法不起作用)
2.spring boot 2.x版本:java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedDataBinder (这里也是两种方法,一种就是使用jdbc,一种是使用SpringBoot 1.5x)
3.SpringBoot 2.1.x 启动报错:java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedDataBin (这里讲了三个方法,其实都没有用,我不能降低SpringBoot版本,提高了Druid版本,没有用,然后就是使用jdbc连接,也没有用)
4.spring boot2 druid java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedDataBinder
5.drtrang/druid-spring-boot (druid-spring-boot2)

2.The connection string contains a badly formed name or value

3.dataSource already closed

这个是我在调用 contextHolder.remove(); 切换回主数据源的时候,出现的问题,

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。