软件编程
位置:首页>> 软件编程>> java编程>> spring boot多数据源动态切换代码实例

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)、结果:

spring boot多数据源动态切换代码实例

来源:https://www.cnblogs.com/cq-yangzhou/p/12172584.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com