1. 引入dynamic-datasource-spring-boot-starter
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>${version}</version> </dependency>
2. 配置数据源
spring:
application:
name: sd-manage-api-provider
datasource:
dynamic:
primary: sdmanage
datasource:
sdmanage:
url: jdbc:oracle:thin:@124.70.91.197:1521/database
username: xxxx
password: 123456
cs:
url: jdbc:oracle:thin:@124.70.91.197:1521/database
username: yyyy
password: 123456
druid:
db-type: oracle
3. dao层类使用@DS("数据源key")即可切换,如@DS("cs")
可参考:https://baomidou.com/guide/dynamic-datasource.html#%E6%96%87%E6%A1%A3-documentation
2. 动态数据源(数据库读取配置,动态加载)
基于springboot的动态数据源,可以通过继承AbstractRoutingDataSource类实现,此处主要包括4个类,DatasourceConfig,DynamicDataSourceContextHolder,DynamicDataSource,SwitchDb
1. 配置bean DynamicDataSource,并向其中添加默认的初始化数据源,其中设置setTargetDataSources()和setDefaultTargetDataSource()是俩最重要的方法
2. 创建用于存储数据源的threadlocal类DynamicDataSourceContextHolder,主要是set和get方法
3. 创建单例DynamicDataSource类, 继承AbstractRoutingDataSource
定义targetDataSources集合和默认的数据源defaultTargetDataSource
定义获取connection的方法
determineTargetDataSource是比较重要的一个方法,用来决定用哪个数据源
1) determineCurrentLookupKey() 用来获取当前数据源的key值,其调用DynamicDataSourceContextHolder中的threadlocal来获取当前的key
2)从目标数据源集合中获取上述获取的key对应的value的数据源,若不存在,则设置为默认的
3)若目标数据源集合不存在且默认的数据源不存在,抛出异常,否则正常返回数据源
单例获取对象方法及判断数据源集合是否包含key方法
4. 配置实际调用的类SwichDb类, 其中最重要的是change()方法和createDataSource()方法
change()方法用于通过key切换数据源,先判断数据源集合中是否已经初始化过本key对应的数据源,若未初始化过,则调用createDataSource()创建,
之后判断当前的key是否已经是需要切换的key,若不是则将threadlocal设置为本key
创建数据源的方法,此处是通过key查询数据库的连接信息,然后创建对应数据库类型的datasource,将其放入targetDataSouces,此处以sqlserver为例
不同类型的数据库只需修改parseToDataSource()方法中的driverClassName和validationQuery即可
5. 实际需要用到切换数据源时,使用change()方法即可
其他:若一个项目想要兼容多个种类的数据源的sql语句语法,可通过在mapper文件配置databaseId实现
1)配置一个configuration
@Bean
public DatabaseIdProvider databaseIdProvider() {
VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
properties.setProperty("Oracle","oracle");
properties.setProperty("MySQL","mysql");
properties.setProperty("SQL Server","sqlserver");
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
2) 在对应的mapper文件的标签上加上上述配置的的value,如
<select id="getApplyBizNumOfLineChartByDay" databaseId="sqlserver" resultType="java.util.Map">
</select>
<select id="getApplyBizNumOfLineChartByDay" databaseId="oracle" resultType="java.util.Map">
</select>