在现代应用程序中,特别是在微服务架构中,经常需要连接多个数据库。在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. 配置数据源
为每个数据源创建配置类,以便分别定义相关的DataSource
、EntityManagerFactory
和TransactionManager
。
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中配置多数据源的一个完整示例。通过这种方式,我们可以轻松管理和使用不同的数据源,以满足复杂应用的需求。在实际开发中,请务必根据实际数据库配置和架构需求来调整配置和代码。