Java 项目中的多数据源实现

在Java项目中,随着业务的不断扩展,常常需要接入多个数据源,例如:关系型数据库、NoSQL数据库等。如何在项目中优雅地实现多个数据源配置与切换,成为开发者面临的一个实际问题。本文将以Spring Boot为例,展示如何通过AbstractRoutingDataSource实现多数据源的切换。

多数据源的背景

在微服务架构中,不同的服务可能会使用不同的数据库。在传统的单一数据源配置中,任何数据库的切换都需要重启应用,降低了灵活性。使用动态数据源可以在运行时根据业务逻辑选择合适的数据源。

实现步骤

以下是实现多个数据源的主要步骤:

1. 项目依赖

首先,在pom.xml中加入Spring Boot及相关数据库依赖,例如MySQL和H2数据库:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

2. 数据源配置

定义多个数据源的配置信息:

spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/primarydb
      username: root
      password: root
    secondary:
      url: jdbc:h2:mem:secondarydb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
      username: sa
      password:

3. 数据源路由

创建一个类 DynamicDataSource 用于实现数据源的动态切换:

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

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

4. 上下文持有者

为了保存当前线程的数据源类型,创建一个上下文持有者 DataSourceContextHolder

public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSourceType(String dataSourceType) {
        contextHolder.set(dataSourceType);
    }

    public static String getDataSourceType() {
        return contextHolder.get();
    }

    public static void clear() {
        contextHolder.remove();
    }
}

5. 数据源切换

在需要切换数据源的地方,可以通过如下方式进行:

DataSourceContextHolder.setDataSourceType("primary");   // 切换到主数据源
// 执行数据库操作
// ...
DataSourceContextHolder.clear(); // 清除当前线程的数据源类型

DataSourceContextHolder.setDataSourceType("secondary"); // 切换到次数据源
// 执行数据库操作
// ...
DataSourceContextHolder.clear(); // 清除当前线程的数据源类型

6. 流程图

以下是整个实现流程的流程图:

flowchart TD
    A[开始] --> B[项目依赖配置]
    B --> C[数据源配置]
    C --> D[实现数据源路由]
    D --> E[实现上下文持有者]
    E --> F[切换数据源]
    F --> G[演示数据操作]
    G --> H[结束]

总结

在Java项目中使用多个数据源提供了灵活性,使得我们可以根据业务需求轻松切换数据库。通过上述步骤,我们可以高效地实现多个数据源的配置和动态切换,提升了代码的可维护性和可测试性。

以下是一个饼状图,用于展示当前项目使用的数据来源比例:

pie
    title 数据来源比例
    "主数据源": 70
    "次数据源": 30

在实际项目中,确保数据源的配置是灵活且易于管理的,将能显著提升系统的可扩展性与可靠性。希望本文提供的示例能够帮助到正在使用多数据源的开发者们。