为了让Spring知道
DataSource
与哪个
Repository
相关,您需要在
@EnableJpaRepositories
注释中定义它。假设我们有两个实体,
Servers
实体和
Domains
实体,每个实体都有自己的Repo,则每个Repo都有自己的JpaDataSource配置。
1. 根据它们所关联的数据源将所有存储库分组。例如:
Domains
实体的Repository(包:
org.springdemo.multiple.datasources.repository.domains
):
package org.springdemo.multiple.datasources.repository.domains;
import org.springdemo.multiple.datasources.domain.domains.Domains;
import org.springframework.data.jpa.repository.JpaRepository;
public interface DomainsRepository extends JpaRepository<Domains,Long> {
}
Servers
实体的仓库(包名:org.springdemo.multiple.datasources.repository.servers
)
package org.springdemo.multiple.datasources.repository.servers;
import org.springdemo.multiple.datasources.domain.servers.Servers;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ServersRepository extends JpaRepository<Servers,Long> {
}
2. 对于每个JPA数据源,您需要定义一个配置。在这个示例中,我展示了如何配置两个不同的数据源。
Domains
Jpa配置:数据源和仓库之间的关系在basePackages
值中定义,因此必须根据每个仓库将使用的实体管理器将仓库分组到不同的包中。
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "domainsEntityManager",
transactionManagerRef = "domainsTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
)
public class DomainsConfig {
服务器
数据源配置:如您所见,basePackages的值具有服务器
存储库的包名称,而且entityManagerFactoryRef
和transactionManagerRef
的值不同,以便让Spring分别管理每个entityManager。
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "serversEntityManager",
transactionManagerRef = "serversTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
)
public class ServersConfig {
3. 将一个数据源设置为主要数据源
为了避免出现错误信息:Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a single bean, but 2 were found:
只需将其中一个数据源设置为 @Primary,例如在这个例子中我选择将 Servers
数据源设置为主要数据源:
@Bean("serversDataSourceProperties")
@Primary
@ConfigurationProperties("app.datasource.servers")
public DataSourceProperties serversDataSourceProperties(){
return new DataSourceProperties();
}
@Bean("serversDataSource")
@Primary
@ConfigurationProperties("app.datasource.servers")
public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) {
return serversDataSourceProperties().initializeDataSourceBuilder().build();
}
如果您需要更多信息,请查看每个配置的完整示例:
Servers JPA 配置
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "serversEntityManager",
transactionManagerRef = "serversTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.servers"}
)
public class ServersConfig {
@Bean(name = "serversEntityManager")
public LocalContainerEntityManagerFactoryBean getServersEntityManager(EntityManagerFactoryBuilder builder,
@Qualifier("serversDataSource") DataSource serversDataSource){
return builder
.dataSource(serversDataSource)
.packages("org.springdemo.multiple.datasources.domain.servers")
.persistenceUnit("servers")
.properties(additionalJpaProperties())
.build();
}
Map<String,?> additionalJpaProperties(){
Map<String,String> map = new HashMap<>();
map.put("hibernate.hbm2ddl.auto", "create");
map.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
map.put("hibernate.show_sql", "true");
return map;
}
@Bean("serversDataSourceProperties")
@Primary
@ConfigurationProperties("app.datasource.servers")
public DataSourceProperties serversDataSourceProperties(){
return new DataSourceProperties();
}
@Bean("serversDataSource")
@Primary
@ConfigurationProperties("app.datasource.servers")
public DataSource serversDataSource(@Qualifier("serversDataSourceProperties") DataSourceProperties serversDataSourceProperties) {
return serversDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean(name = "serversTransactionManager")
public JpaTransactionManager transactionManager(@Qualifier("serversEntityManager") EntityManagerFactory serversEntityManager){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(serversEntityManager);
return transactionManager;
}
}
域名
JPA 配置
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "domainsEntityManager",
transactionManagerRef = "domainsTransactionManager",
basePackages = {"org.springdemo.multiple.datasources.repository.domains"}
)
public class DomainsConfig {
@Bean(name = "domainsEntityManager")
public LocalContainerEntityManagerFactoryBean getdomainsEntityManager(EntityManagerFactoryBuilder builder
,@Qualifier("domainsDataSource") DataSource domainsDataSource){
return builder
.dataSource(domainsDataSource)
.packages("org.springdemo.multiple.datasources.domain.domains")
.persistenceUnit("domains")
.properties(additionalJpaProperties())
.build();
}
Map<String,?> additionalJpaProperties(){
Map<String,String> map = new HashMap<>();
map.put("hibernate.hbm2ddl.auto", "create");
map.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
map.put("hibernate.show_sql", "true");
return map;
}
@Bean("domainsDataSourceProperties")
@ConfigurationProperties("app.datasource.domains")
public DataSourceProperties domainsDataSourceProperties(){
return new DataSourceProperties();
}
@Bean("domainsDataSource")
public DataSource domainsDataSource(@Qualifier("domainsDataSourceProperties") DataSourceProperties domainsDataSourceProperties) {
return domainsDataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean(name = "domainsTransactionManager")
public JpaTransactionManager transactionManager(@Qualifier("domainsEntityManager") EntityManagerFactory domainsEntityManager){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(domainsEntityManager);
return transactionManager;
}
}
为了分离每个数据源,我将配置放在
application.properties
文件中,像这样:
app.datasource.domains.url=jdbc:h2:mem:~/test
app.datasource.domains.driver-class-name=org.h2.Driver
app.datasource.servers.driver-class-name=com.mysql.jdbc.Driver
app.datasource.servers.url=jdbc:mysql://localhost:3306/v?autoReconnect=true&useSSL=false
app.datasource.servers.username=myuser
app.datasource.servers.password=mypass
如果需要更多信息请参考以下文档:
Spring文档:如何配置两个数据源
如何配置两个不同数据库的类似示例:Github示例