为了让spring知道
DataSource与之相关的内容,
Repository你应该在
@EnableJpaRepositories注释中对其进行定义。假设我们有两个实体,
Servers实体和
Domains实体,并且每个实体都有自己的存储库,那么每个存储库都有自己的JpaDataSource配置。
1.根据与它们相关的数据源将所有存储库分组。例如
Domains实体存储库(包:)
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 Data Soruce,你需要定义一个配置,在此示例中,我演示了如何配置两个不同的DataSources
DomainsJpa配置:
basePackages值中定义了数据源与存储库之间的关系,这就是为什么有必要根据每个存储库将使用的实体管理器将存储库分组到不同程序包中的原因。
@Configuration@EnableJpaRepositories( entityManagerFactoryRef = "domainsEntityManager", transactionManagerRef = "domainsTransactionManager", basePackages = {"org.springdemo.multiple.datasources.repository.domains"} )public class DomainsConfig {Servers数据源配置:正如你所看到的basePackages值具有的包名
Servers库,并且还值
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; }}Domains 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:~/testapp.datasource.domains.driver-class-name=org.h2.Driverapp.datasource.servers.driver-class-name=com.mysql.jdbc.Driverapp.datasource.servers.url=jdbc:mysql://localhost:3306/v?autoReconnect=true&useSSL=falseapp.datasource.servers.username=myuserapp.datasource.servers.password=mypass



