场景
在使用Spring Data JPA的服务中, 需要同时连接自己的数据库进行增删改查, 也需要连接一个外部提供的数据库查询数据. 因此需要维护两套数据库配置.
实现思路
首先使用JPA一般都需要domain实体和repository. 规划为:
- 主数据库的实体都放到统一包
domain
下, repository放repository
下 - 第二套数据库的实体都放到统一包
share.domain
下, repository放share.repository
下
然后通过配置两套持久化单元,并分别指定扫描的包,完成两套数据库配置. 然后就可以通过调用repository分别实现对两套数据库的调用了.
主数据库的结构
./example/domain/User.java
./example/repository/UserRepository.java
第二套数据库结构
./example/share/domain/School.java
./example/share/repository/SchoolRepository.java
具体实现
1. 主数据库配置
主数据库配置
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.EnableJpaAuditing;
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
@EnableJpaAuditing
@EnableTransactionManagement
// 指定扫描的仓库目录
@EnableJpaRepositories(basePackages = {"example.repository"}, entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
public class DatabaseConfiguration {@Bean(name = "primaryDataSourceProperties")@ConfigurationProperties("spring.datasource")@Primarypublic DataSourceProperties dataSourceProperties() {return new DataSourceProperties();}@Primary@Bean(name = "dataSource")@ConfigurationProperties("spring.datasource.hikari")public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();}@Primary@Bean(name = "entityManagerFactory")public LocalContainerEntityManagerFactoryBeanentityManagerFactory(EntityManagerFactoryBuilder builder,DataSource dataSource) {return builder.dataSource(dataSource)// 指定扫描包.packages("example.domain").persistenceUnit("primary-domain").build();}@Primary@Bean(name = "transactionManager")public PlatformTransactionManager transactionManager(EntityManagerFactoryentityManagerFactory) {return new JpaTransactionManager(entityManagerFactory);}}
第二套数据库配置
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 = {"example.share.repository"}, entityManagerFactoryRef = "shareEntityManagerFactory", transactionManagerRef = "shareTransactionManager")
public class DatabaseShareConfiguration {@Bean(name = "shareDataSourceProperties")// 指定数据库配置前缀,然后可以通过 share.datasource.url 这种格式去配置第二套数据源配置@ConfigurationProperties("share.datasource")public DataSourceProperties dataSourceProperties() {return new DataSourceProperties();}@Bean(name = "shareDataSource")// 指定数据库配置前缀,然后可以通过 share.datasource.hikari.poolName 这种格式去配置第二套数据源配置@ConfigurationProperties("share.datasource.hikari")public DataSource dataSource(@Qualifier("shareDataSourceProperties") DataSourceProperties dataSourceProperties) {return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();}@Bean(name = "shareEntityManagerFactory")public LocalContainerEntityManagerFactoryBeanshareEntityManagerFactory(EntityManagerFactoryBuilder builder,@Qualifier("shareDataSource") DataSource dataSource) {returnbuilder.dataSource(dataSource)// 指定扫描包地址.packages("example.share.domain").persistenceUnit("share").build();}@Bean(name = "shareTransactionManager")public PlatformTransactionManager shareTransactionManager(@Qualifier("shareEntityManagerFactory") EntityManagerFactoryshareEntityManagerFactory) {return new JpaTransactionManager(shareEntityManagerFactory);}
}
application.yml
# 主数据库配置
spring:datasource:type: com.zaxxer.hikari.HikariDataSourceusername: rooturl: jdbc:mysql://localhost:3306/password: hikari:poolName: Hikariauto-commit: false# 第二套数据库配置
share:datasource:type: com.zaxxer.hikari.HikariDataSourceurl: jdbc:mysql://localhost:3307/username: rootpassword:hikari:poolName: Share-Hikariauto-commit: false