在现代应用程序中,特别是在微服务架构中,经常需要连接多个数据库。在Java中,我们可以通过配置多数据源来实现这一需求。本文将介绍如何在Spring Boot应用中配置多数据源,确保你能够灵活地使用不同的数据源进行数据库操作。

多数据源的概念

多数据源的概念是指应用程序同时连接到多个数据库实例。每个数据源可以有不同的数据库类型、配置和连接字符串。在某些情况下,我们可能需要将数据存储在不同的数据库中,例如分离读写数据库或根据不同的业务模块使用不同的数据库。

Spring Boot多数据源配置示例

下面是如何在Spring Boot中配置多数据源的示例。

1. 引入依赖

确保你的pom.xml中包含了Spring Boot Starter和数据库驱动(例如MySQL)依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

2. 配置application.yml

application.yml中配置两个数据源的连接信息。例如:

spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/primary_db
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
    secondary:
      url: jdbc:mysql://localhost:3306/secondary_db
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver

3. 配置数据源

为每个数据源创建配置类,以便分别定义相关的DataSourceEntityManagerFactoryTransactionManager

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import javax.annotation.Resource;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.demo.primary.repository", 
    entityManagerFactoryRef = "primaryEntityManagerFactory", 
    transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDataSourceConfig {

    @Primary
    @Bean(name = "primaryDataSource")
    public DataSource primaryDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/primary_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("primaryDataSource") DataSource primaryDataSource) {
        return builder
                .dataSource(primaryDataSource)
                .packages("com.example.demo.primary.entity") // 设置实体类扫描包
                .persistenceUnit("primary")
                .build();
    }

    @Primary
    @Bean(name = "primaryTransactionManager")
    public JpaTransactionManager primaryTransactionManager(
            @Qualifier("primaryEntityManagerFactory") EntityManagerFactory primaryEntityManagerFactory) {
        return new JpaTransactionManager(primaryEntityManagerFactory);
    }
}

对于第二个数据源,配置逻辑类似,只需替换相关的bean名称和扫描的包名即可:

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.demo.secondary.repository", 
    entityManagerFactoryRef = "secondaryEntityManagerFactory", 
    transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDataSourceConfig {

    @Bean(name = "secondaryDataSource")
    public DataSource secondaryDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/secondary_db");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    @Bean(name = "secondaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
        return builder
                .dataSource(secondaryDataSource)
                .packages("com.example.demo.secondary.entity") // 设置实体类扫描包
                .persistenceUnit("secondary")
                .build();
    }

    @Bean(name = "secondaryTransactionManager")
    public JpaTransactionManager secondaryTransactionManager(
            @Qualifier("secondaryEntityManagerFactory") EntityManagerFactory secondaryEntityManagerFactory) {
        return new JpaTransactionManager(secondaryEntityManagerFactory);
    }
}

4. 使用数据源

在你的服务层中,你可以通过注入相应的数据源来执行数据库操作。例如:

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

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository; // Primary DataSource

    @Autowired
    private SecondaryUserRepository secondaryUserRepository; // Secondary DataSource

    public User getUserFromPrimaryDB(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    public SecondaryUser getUserFromSecondaryDB(Long id) {
        return secondaryUserRepository.findById(id).orElse(null);
    }
}

总结

以上就是在Spring Boot中配置多数据源的一个完整示例。通过这种方式,我们可以轻松管理和使用不同的数据源,以满足复杂应用的需求。在实际开发中,请务必根据实际数据库配置和架构需求来调整配置和代码。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部