spring boot多数据源动态切换代码实例
作者:炫舞风中 发布时间:2022-03-11 00:37:09
标签:spring,boot,数据源,动态,切换
这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下。
1、maven依赖
<!--数据库连接-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
<scope>runtime</scope>
</dependency>
<!--数据库连接池->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--aop->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、多数据源信息配置
#多数据源测试
spring:
datasource:
druid:
master:
driver-class-name: oracle.jdbc.driver.OracleDriver
username: test
password: test
url: jdbc:oracle:thin:@//ip1:1521/orcl
slave:
driver-class-name: oracle.jdbc.driver.OracleDriver
username: test
password: test
url: jdbc:oracle:thin:@//ip2:1521/orcl
3、数据源配置信息转换成实体类
@ConfigurationProperties(prefix = "spring.datasource.druid")
@Data
@Component
public class DataSourceProperties {
private Map<String,String>master;
private Map<String,String>slave;
}
4、动态数据源切换类
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
5、多数据源配置类
@Configuration
public class DynamicDataSourceConfig {
@Bean
public DataSource master(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource = new DruidDataSource();
Map<String, String> master = dataSourceProperties.getMaster();
druidDataSource.setUsername(master.get("username"));
druidDataSource.setPassword(master.get("password"));
druidDataSource.setUrl(master.get("url"));
//其他参数配置 省略
return druidDataSource;
}
@Bean
public DataSource slave(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource = new DruidDataSource();
Map<String, String> slave = dataSourceProperties.getSlave();
druidDataSource.setUsername(slave.get("username"));
druidDataSource.setPassword(slave.get("password"));
druidDataSource.setUrl(slave.get("url"));
//其他参数配置 省略
return druidDataSource;
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource master,DataSource slave){
Map<Object,Object>map = new HashMap<>(4);
map.put("master",master);
map.put("slave",slave);
return new DynamicDataSource(master,map);
}
}
6、自定义@DataSource注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String name() default "master";
}
7、Aop切面类配置
@Component
@Aspect
public class DataSourceAspect {
@Pointcut("@annotation(com.zxgeo.sso.muiltDatasource.anons.DataSource)")
public void dataSourcePointCut(){}
@Around(value = "dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if(dataSource == null){
DynamicDataSource.setDataSource("master");
}else {
DynamicDataSource.setDataSource(dataSource.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
8、启动配置注解信息,重要(不然运行会报错)
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
9、测试
(1)、service层(此处没有使用mybatis)
@Service
public class TestService {
@Autowired
private javax.sql.DataSource dataSource;
@DataSource
public Map<String,Object> getMasterDataSource() throws SQLException {
Connection connection = dataSource.getConnection();
Map<String,Object> map;
try (PreparedStatement preparedStatement
= connection.prepareStatement("SELECT * FROM AA WHERE A=10001")) {
ResultSet resultSet = preparedStatement.executeQuery();
map = new HashMap<>();
while (resultSet.next()){
map.put("A",resultSet.getString("A"));
map.put("B",resultSet.getString("B"));
map.put("C",resultSet.getString("C"));
}
}
return map;
}
@DataSource(name = "slave")
public Map<String,Object> getSlaveDataSource() throws SQLException {
Connection connection = dataSource.getConnection();
Map<String,Object> map;
try (PreparedStatement preparedStatement
= connection.prepareStatement("SELECT * FROM AA WHERE A=10002")) {
ResultSet resultSet = preparedStatement.executeQuery();
map = new HashMap<>();
while (resultSet.next()){
map.put("A",resultSet.getString("A"));
map.put("B",resultSet.getString("B"));
map.put("C",resultSet.getString("C"));
}
}
return map;
}
}
(2)、单元测试
@SpringBootTest
@RunWith(SpringRunner.class)
class SsoApplicationTests {
@Autowired
private TestService testService;
@Test
public void muliDatasorce() throws SQLException {
Map<String, Object> masterDataSourceUrl = testService.getMasterDataSource();
System.out.println(masterDataSourceUrl);
Map<String, Object> slaveDataSourceUrl = testService.getSlaveDataSource();
System.out.println(slaveDataSourceUrl);
}
}
(3)、结果:
来源:https://www.cnblogs.com/cq-yangzhou/p/12172584.html


猜你喜欢
- 本文实例为大家分享了抢红包源码,供大家参考,具体内容如下1. 正确获取红包流程2. 软件介绍2.1 效果图:2.2 功能介绍2.2.1 账号
- 在系统的管理员有着实际的应用,对于一个数据库管理系统来说,数据库安全还是挺重要的,所以在存入到数据库的密码通常都是加密的。即使有着hack攻
- 系统需要用到一个导入excel文件的功能,使用poi组件常规方式读取excel时,内存耗尽,OutOfMemoryError,或者读取非常慢
- 提供表示 Windows 注册表中的根项的 RegistryKey 对象,并提供访问项/值对的 static&
- 所谓回调,就是客户程序C调用服务程序S中的某个方法A,然后S又在某个时候反过来调用C中的某个方法B,对于C来说,这个B便叫做回调方法。下面看
- 一、HashMap概述HashMap基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键
- 访问控制:private 私有的protected 受保护的public 公共的类、方法和变量修饰符abstract 声明抽象class 类
- SpringCloud @FeignClient 参数详解今天因为工作中遇到FeignClient一个奇葩的bug,后面仔细研究了,找出了原
- MyBatis介绍MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software
- 本文实例为大家分享了Java使用MulticastSocket实现群聊应用程序的具体代码,供大家参考,具体内容如下在这篇文章中,讨论了一个使
- 一、定时任务的使用场景和常见的定时任务某个时间定时处理某个任务、发邮件、短信、消息提醒、订单通知、统计报表等定时任务划分单机定时任务:单机的
- eclipse汉化包我们会经常用到,因为它可以帮助英语基础差的用户更快的掌握这个软件,非常方便,但是我看了下整个互联网上并没有对这个汉化包进
- 在用maven打包时,出现过如下两个错误:错误1:程序包javax.servlet不存在,程序包javax.servlet.http不存在错
- 如下所示:using System;using System.Collections.Generic;using System.Text;n
- 一. 多任务和Task、启动模式Android 手机在早期,下方通常会内置三个实体的触摸按键,分别是:桌面、菜单、返回。大概在Android
- 目录1. 简单认识BeanProcessorBeanProcessor的理解一个BeanProcessor的使用实例2. BeanProce
- 什么是EurekaNetflix Eureka 是一款由 Netflix 开源的基于 REST 服务的注册中心,用于提供服务发现功能。Spr
- 本文实例讲述了C#计算字符串相似性的方法。分享给大家供大家参考。具体如下:计算字符串相似性的办法很多,甚至最笨的办法可以挨个匹配,这里要讲的
- 一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。例如第6页用6表示而不是06或0
- 这篇文章主要介绍了Spring @Transactional注解失效解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的