在Spring Boot中配置多个数据源需要完成以下步骤:
- 引入相关依赖
在pom.xml
文件中添加以下依赖:
<!-- Spring Boot JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
- 配置多个数据源
在application.yml
中配置多个数据源的连接信息:
spring:
datasource:
primary:
jdbc-url: jdbc:mysql://localhost:3306/primary?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
secondary:
jdbc-url: jdbc:mysql://localhost:3306/secondary?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
jpa:
hibernate:
ddl-auto: none # 不自动创建表结构
show-sql: true # 显示 SQL
上述配置中定义了两个数据源,一个是primary,一个是secondary。可以根据实际情况自行替换。
- 定义数据源实例
在@Configuration
注解标识的类中,定义两个数据源实例:
@Configuration
public class DataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
上述代码中,使用@Primary
注解标识了primary数据源,当系统中存在多个数据源时,@Primary注解会将这个数据源优先注入到需要使用的地方。
- 创建EntityManagerFactory
在@Configuration
注解标识的类中,创建两个EntityManagerFactory实例:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager",
basePackages = {"com.example.demo.primary.repository"})
public class PrimaryDataSourceConfig {
@Bean(name = "primaryEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.example.demo.primary.entity")
.persistenceUnit("primaryPersistenceUnit").build();
}
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) {
return builder.dataSource(dataSource).packages("com.example.demo.secondary.entity")
.persistenceUnit("secondaryPersistenceUnit").build();
}
}
创建TransactionManager
在@Configuration注解标识的类中,创建两个TransactionManager实例:
@Configuration
@EnableTransactionManagement
public class TransactionManagerConfig {
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager primaryTransactionManager(
@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(
@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
使用数据源
在使用数据源时,需要使用@Qualifier注解指定使用哪个数据源:
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("primaryEntityManagerFactory")
private EntityManagerFactory primaryEntityManagerFactory;
@Autowired
@Qualifier("secondaryEntityManagerFactory")
private EntityManagerFactory secondaryEntityManagerFactory;
@Transactional(transactionManager = "primaryTransactionManager")
@Override
public void addUser(User user) {
EntityManager entityManager = primaryEntityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(user);
entityManager.getTransaction().commit();
entityManager.close();
}
@Transactional(transactionManager = "secondaryTransactionManager")
@Override
public void updateUser(User user) {
EntityManager entityManager = secondaryEntityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
entityManager.merge(user);
entityManager.getTransaction().commit();
entityManager.close();
}
}
上述代码中,@Transactional注解中的transactionManager属性指定了具体使用的TransactionManager。同时,在获取EntityManagerFactory实例时,需要使用@Qualifier注解指定具体的数据源。