面试题:在 Spring Boot 中如何实现多数据源配置?

在 Spring Boot 中,多数据源配置是一个常见的需求,尤其是在需要连接多个数据库的场景中。以下是实现多数据源配置的详细步骤:


1. 添加依赖

首先,确保在 pom.xml 中引入了 Spring Boot 的数据库依赖(如 MySQL、PostgreSQL 等)。

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

2. 配置多数据源

application.ymlapplication.properties 中配置多个数据源的连接信息。

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

3. 配置数据源 Bean

在 Java 配置类中定义多个数据源的 DataSource Bean。

   import org.springframework.boot.context.properties.ConfigurationProperties;
   import org.springframework.boot.jdbc.DataSourceBuilder;
   import org.springframework.context.annotation.Bean;
   import org.springframework.context.annotation.Configuration;
   import org.springframework.context.annotation.Primary;

   import javax.sql.DataSource;

   @Configuration
   public class DataSourceConfig {

       @Primary // 主数据源
       @Bean(name = "primaryDataSource")
       @ConfigurationProperties(prefix = "spring.datasource.primary")
       public DataSource primaryDataSource() {
           return DataSourceBuilder.create().build();
       }

       @Bean(name = "secondaryDataSource")
       @ConfigurationProperties(prefix = "spring.datasource.secondary")
       public DataSource secondaryDataSource() {
           return DataSourceBuilder.create().build();
       }
   }

4. 配置 JPA 实体管理器

为每个数据源配置独立的 EntityManagerFactoryTransactionManager

   import org.springframework.beans.factory.annotation.Qualifier;
   import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
   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.transaction.PlatformTransactionManager;
   import org.springframework.transaction.annotation.EnableTransactionManagement;

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

   @Configuration
   @EnableTransactionManagement
   @EnableJpaRepositories(
       basePackages = "com.example.repository.primary", // 主数据源的 Repository 包路径
       entityManagerFactoryRef = "primaryEntityManagerFactory",
       transactionManagerRef = "primaryTransactionManager"
   )
   public class PrimaryDataSourceConfig {

       @Bean(name = "primaryEntityManagerFactory")
       public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
           EntityManagerFactoryBuilder builder,
           @Qualifier("primaryDataSource") DataSource dataSource) {
           return builder
               .dataSource(dataSource)
               .packages("com.example.entity.primary") // 主数据源的实体类包路径
               .persistenceUnit("primary")
               .build();
       }

       @Bean(name = "primaryTransactionManager")
       public PlatformTransactionManager primaryTransactionManager(
           @Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
           return new JpaTransactionManager(entityManagerFactory);
       }
   }
   import org.springframework.beans.factory.annotation.Qualifier;
   import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
   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.transaction.PlatformTransactionManager;

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

   @Configuration
   @EnableJpaRepositories(
       basePackages = "com.example.repository.secondary", // 次数据源的 Repository 包路径
       entityManagerFactoryRef = "secondaryEntityManagerFactory",
       transactionManagerRef = "secondaryTransactionManager"
   )
   public class SecondaryDataSourceConfig {

       @Bean(name = "secondaryEntityManagerFactory")
       public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
           EntityManagerFactoryBuilder builder,
           @Qualifier("secondaryDataSource") DataSource dataSource) {
           return builder
               .dataSource(dataSource)
               .packages("com.example.entity.secondary") // 次数据源的实体类包路径
               .persistenceUnit("secondary")
               .build();
       }

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

5. 定义实体类和 Repository

为每个数据源定义独立的实体类和 Repository 接口。

主数据源实体类

   package com.example.entity.primary;

   import javax.persistence.Entity;
   import javax.persistence.GeneratedValue;
   import javax.persistence.GenerationType;
   import javax.persistence.Id;

   @Entity
   public class User {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
       private String name;
       // getters and setters
   }

主数据源 Repository

   package com.example.repository.primary;

   import com.example.entity.primary.User;
   import org.springframework.data.jpa.repository.JpaRepository;

   public interface UserRepository extends JpaRepository<User, Long> {
   }

次数据源实体类

   package com.example.entity.secondary;

   import javax.persistence.Entity;
   import javax.persistence.GeneratedValue;
   import javax.persistence.GenerationType;
   import javax.persistence.Id;

   @Entity
   public class Product {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
       private String name;
       // getters and setters
   }

次数据源 Repository

   package com.example.repository.secondary;

   import com.example.entity.secondary.Product;
   import org.springframework.data.jpa.repository.JpaRepository;

   public interface ProductRepository extends JpaRepository<Product, Long> {
   }

6. 测试多数据源

在 Service 或 Controller 中注入不同的 Repository,测试多数据源是否正常工作。

   import com.example.repository.primary.UserRepository;
   import com.example.repository.secondary.ProductRepository;
   import org.springframework.beans.factory.annotation.Autowired;
   import org.springframework.stereotype.Service;

   @Service
   public class MyService {
       @Autowired
       private UserRepository userRepository;

       @Autowired
       private ProductRepository productRepository;

       public void testMultiDataSource() {
           userRepository.findAll().forEach(System.out::println);
           productRepository.findAll().forEach(System.out::println);
       }
   }

总结

通过以上步骤,可以在 Spring Boot 中实现多数据源配置。关键点包括:

  1. 配置多个数据源的连接信息。
  2. 定义多个 DataSource Bean。
  3. 为每个数据源配置独立的 EntityManagerFactoryTransactionManager
  4. 定义独立的实体类和 Repository 接口。

这种方式适用于需要连接多个数据库的场景,能够有效隔离不同数据源的操作。

THE END
点赞11 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容