springboot+dynamicDataSource动态添加切换数据源方式

使用 Spring Boot,可以动态添加切换数据源,需要用到Spring JDBC模块中的 AbstractRoutingDataSource 类和 DynamicDataSourceHolder 维护一个存储当前使用的数据源 key 的 ThreadLocal 对象。步骤如下:

导入依赖

首先,在 pom.xml 中导入 Spring Boot 和 Spring JDBC 的依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

定义数据源

其次,在 application.yml 中定义数据源。

spring:
  datasource:
    default:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
      username: root
      password: root
    db1:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=UTF-8
      username: root
      password: root
    db2:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=UTF-8
      username: root
      password: root

定义动态数据源

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

维护当前使用数据源的 key

public class DynamicDataSourceHolder {
    private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<>();

    public static void setDataSourceKey(String key) {
        dataSourceKey.set(key);
    }

    public static String getDataSourceKey() {
        return dataSourceKey.get();
    }

    public static void clearDataSourceKey() {
        dataSourceKey.remove();
    }
}

配置动态数据源

@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource defaultDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.db1")
    public DataSource db1DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.db2")
    public DataSource db2DataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public DynamicDataSource dynamicDataSource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("default", defaultDataSource());
        targetDataSources.put("db1", db1DataSource());
        targetDataSources.put("db2", db2DataSource());

        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(defaultDataSource());

        return dynamicDataSource;
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dynamicDataSource);

        return sqlSessionFactory;
    }
}

上述代码中,@ConfigurationProperties("spring.datasource") 表示读取 yml 配置文件中的 spring.datasource 参数,这里将 default 数据源的信息读入 DataSource 中,其他两个数据源同理。DynamicDataSource 类是继承了 Spring JDBC 中的 AbstractRoutingDataSource 类,它会调用 DynamicDataSourceHolder 中的 getDataSourceKey() 方法获取当前数据源 key,然后根据这个 key 从 targetDataSources 中取出对应的数据源。

测试

为了方便测试,我们添加 Controller 和 Service。

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User findById(@PathVariable Integer id, @RequestParam String db) {
        DynamicDataSourceHolder.setDataSourceKey(db);
        User user = userService.findById(id);
        DynamicDataSourceHolder.clearDataSourceKey();

        return user;
    }
}

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User findById(Integer id) {
        return userMapper.findById(id);
    }
}

@Mapper
public interface UserMapper {
    User findById(Integer id);
}

这个示例中,我们为 Controller 增加了一个请求参数 db,它的值可以是 default、db1 或 db2,为了测试是否切换了数据源,我们在 findById() 方法中调用 DynamicDataSourceHolder.setDataSourceKey() 方法设置数据源 key,然后在调用 UserService.findById() 方法完成查询后,调用 DynamicDataSourceHolder.clearDataSourceKey() 方法清除数据源 key,这样就完成了数据源的切换。

$ curl http://localhost:8080/user/1?db=db1
{"id":1,"name":"User 1","age":20}
$ curl http://localhost:8080/user/2?db=db2
{"id":2,"name":"User 2","age":30}

根据访问地址中的 db 参数的值,会分别从 db1 和 db2 数据库中查询数据。

可以看到,使用 Spring Boot 实现动态添加切换数据源非常简单。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot+dynamicDataSource动态添加切换数据源方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • oracle如何使用java source调用外部程序

    使用 Java Source 调用外部程序可以让我们在 Oracle 数据库中调用其他程序的功能,这在实际应用中非常实用。以下是详细讲解 “oracle如何使用java source调用外部程序” 的完整攻略: 1. 安装JDK 安装JDK,安装目录路径如下,如以不同版本安装需按对应路径进行修改。 Linux:/usr/java/jdk1.8.0_281Wi…

    Java 2023年5月26日
    00
  • 多jdk环境下指定springboot外部配置文件详解

    下面是多jdk环境下指定springboot外部配置文件的完整攻略: 1. 背景 通常我们在开发中使用Spring Boot时,会使用application.properties或application.yml来进行配置,但是如果我们需要在不同的JDK环境中进行配置,这个时候就需要指定外部配置文件,以满足我们在不同环境下能够进行正确的配置。 2. 步骤 以下…

    Java 2023年5月19日
    00
  • Java环境配置原理全面解析

    这里是关于Java环境配置原理全面解析的详细攻略。 简介 Java是一种跨平台编程语言,需要安装Java开发工具包(JDK)才能进行编码,因此在进行Java编程之前必须进行Java环境的安装和配置。 Java环境配置的主要内容包括: 安装JDK 配置环境变量 本文将逐一介绍这两个过程,并附带两个实际的安装示例。 安装JDK JDK的安装需要从Oracle官网…

    Java 2023年5月24日
    00
  • springdata jpa单表操作crud的实例代码详解

    下面我将为您详细讲解“springdata jpa单表操作crud的实例代码详解”的完整攻略。 一、前言 Spring Data JPA是Spring Data中一个很重要的模块,可以方便地进行关系型数据库的访问和操作。在本篇攻略中,我们将详细讲解如何使用Spring Data JPA进行单表操作CRUD。 二、准备工作 在使用Spring Data JPA…

    Java 2023年5月20日
    00
  • Java语法基础之函数的使用说明

    Java语法基础之函数的使用说明 在Java中,函数是一个非常重要且常用的机制,我们可以使用它来封装代码,实现模块化以及实现代码的复用,本文将详细讲解Java函数的使用说明,包括函数的定义、调用、参数和返回值等内容。 函数的定义 在Java中,函数的定义包括函数名、参数列表和函数体,它的基本语法如下: [修饰符] 返回类型 函数名(参数列表) { 函数体 }…

    Java 2023年5月23日
    00
  • 基于resty orm的ActiveRecord操作数据指南

    基于resty orm的ActiveRecord操作数据指南 什么是ActiveRecord ActiveRecord 是一种 ORM 模式,在该模式下,对象的属性映射到数据库表的字段,一行记录对应于一个对象实例。 什么是resty orm resty orm 是 OpenResty 中提供的 ORM 实现,它支持 MySQL、PostgreSQL 和 Re…

    Java 2023年5月20日
    00
  • Java实现的mysql事务处理操作示例

    当我们想要在Java应用程序中使用MySQL数据库时,需要处理事务操作。这里,我将向您展示如何使用Java和JDBC来处理MySQL事务。下面是一个完整攻略: 1. 添加MySQL JDBC驱动 在使用MySQL数据库之前,我们需要在Java项目中添加相应的MySQL JDBC驱动。您可以从官方网站下载最新的JDBC驱动程序,也可以使用第三方依赖管理工具,如…

    Java 2023年5月19日
    00
  • Java使用JDBC实现Oracle用户认证的方法详解

    Java使用JDBC实现Oracle用户认证的方法 示例1:使用JDBC连接Oracle数据库 在Java中使用JDBC连接Oracle数据库,主要需要使用以下步骤: 加载数据库驱动程序; 创建数据库连接; 创建Statement对象; 执行SQL语句; 处理结果; 关闭连接。 以下是一个简单的示例代码: import java.sql.*; public …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部