实现Java config配置多个数据源的步骤

在现代企业应用中,通常需要支持多个数据源以满足不同的数据访问需求。为了帮助你理解如何在Java应用中用配置文件(Java Config)配置多个数据源,下面是整个流程的概述以及每一步的详细代码实现。

流程概述

首先,让我们创建一个简洁的表格,展示实现的各个步骤:

步骤编号 步骤描述 代码片段/说明
1 创建Application类 创建Spring Boot应用的主类
2 配置第一个数据源 实现DataSource和EntityManagerFactory
3 配置第二个数据源 实现第二个DataSource和EntityManagerFactory
4 配置事务管理 配置PlatformTransactionManager
5 创建Repository 创建Repository接口
6 使用数据源 在Service层中使用Repository

每一步的详细实现

步骤1:创建Application类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MultiDataSourceApplication {
    public static void main(String[] args) {
        SpringApplication.run(MultiDataSourceApplication.class, args);
    }
}

上面的代码是 Spring Boot 应用的主入口,负责启动应用程序。

步骤2:配置第一个数据源

首先需要配置一个数据源。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(basePackages = "com.example.repository.datasource1",
    entityManagerFactoryRef = "dataSource1EntityManagerFactory",
    transactionManagerRef = "dataSource1TransactionManager")
public class DataSource1Config {

    @Bean
    public DataSource dataSource1() {
        // 创建第一个数据源配置
        return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/db1")
            .username("user1")
            .password("pass1")
            .driverClassName("com.mysql.cj.jdbc.Driver")
            .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean dataSource1EntityManagerFactory() {
        // 创建第一个EntityManagerFactory
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource1());
        em.setPackagesToScan("com.example.entity.datasource1");
        return em;
    }

    @Bean
    public JpaTransactionManager dataSource1TransactionManager(EntityManagerFactory dataSource1EntityManagerFactory) {
        // 创建第一个事务管理器
        return new JpaTransactionManager(dataSource1EntityManagerFactory);
    }
}

在这段代码中,我们创建了第一个数据源的配置,包括 DataSourceEntityManagerFactoryTransactionManager

步骤3:配置第二个数据源

与第一个数据源类似,下面是第二个数据源的配置。

@Configuration
@EnableJpaRepositories(basePackages = "com.example.repository.datasource2",
    entityManagerFactoryRef = "dataSource2EntityManagerFactory",
    transactionManagerRef = "dataSource2TransactionManager")
public class DataSource2Config {

    @Bean
    public DataSource dataSource2() {
        // 创建第二个数据源配置
        return DataSourceBuilder.create()
            .url("jdbc:mysql://localhost:3306/db2")
            .username("user2")
            .password("pass2")
            .driverClassName("com.mysql.cj.jdbc.Driver")
            .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean dataSource2EntityManagerFactory() {
        // 创建第二个EntityManagerFactory
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource2());
        em.setPackagesToScan("com.example.entity.datasource2");
        return em;
    }

    @Bean
    public JpaTransactionManager dataSource2TransactionManager(EntityManagerFactory dataSource2EntityManagerFactory) {
        // 创建第二个事务管理器
        return new JpaTransactionManager(dataSource2EntityManagerFactory);
    }
}

这段代码类似于第一个数据源的配置,只是针对第二个数据源。

步骤4:配置事务管理

在这两步中,我们已经为两个数据源分别创建了事务管理器。可以根据需要在业务逻辑中进行选择使用。

步骤5:创建Repository

com.example.repository.datasource1com.example.repository.datasource2下分别创建Repository接口。

import org.springframework.data.jpa.repository.JpaRepository;

public interface DataSource1Repository extends JpaRepository<EntityClass1, Long> {
    // 数据源1的Repository接口
}

public interface DataSource2Repository extends JpaRepository<EntityClass2, Long> {
    // 数据源2的Repository接口
}

步骤6:使用数据源

在服务中使用这两个数据源的Repository。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Autowired
    private DataSource1Repository dataSource1Repo;

    @Autowired
    private DataSource2Repository dataSource2Repo;

    public void performDatabaseOperations() {
        // 使用数据源1的操作
        dataSource1Repo.save(new EntityClass1());
        
        // 使用数据源2的操作
        dataSource2Repo.save(new EntityClass2());
    }
}

上面的代码演示了如何在业务逻辑层中使用这两个数据源的Repository进行数据操作。

状态图

使用 mermaid 语法可以表示代码执行的状态流程。

stateDiagram
    [*] --> Application_Started
    Application_Started --> DataSource1_Configured
    Application_Started --> DataSource2_Configured
    DataSource1_Configured --> TransactionManager1_Configured
    DataSource2_Configured --> TransactionManager2_Configured
    TransactionManager1_Configured --> Repository1_Created
    TransactionManager2_Configured --> Repository2_Created

结尾

通过以上步骤,我们成功地在Java应用中实现了多个数据源的配置。希望你能通过这个示例不断练习,熟悉Spring配置多个数据源的方式。在实际项目中,需求可能更加复杂,但掌握了基础概念、流程和代码,上述配置将是一个良好的起点。只要运用得当,你就能够轻松构建出一个高效、灵活的数据访问层。