上一篇咱們介紹了在使用JdbcTemplate來作數據訪問時候的多數據源配置實現。接下來咱們繼續學習如何在使用Spring Data JPA的時候,完成多數據源的配置和使用。java
先在Spring Boot的配置文件application.properties
中設置兩個你要連接的數據庫配置,好比這樣:mysql
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1 spring.datasource.primary.username=root spring.datasource.primary.password=123456 spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2 spring.datasource.secondary.username=root spring.datasource.secondary.password=123456 spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver # 日誌打印執行的SQL spring.jpa.show-sql=true # Hibernate的DDL策略 spring.jpa.hibernate.ddl-auto=create-drop
這裏除了JPA自身相關的配置以外,與JdbcTemplate配置時候的數據源配置徹底是一致的git
說明與注意:github
spring.datasource
以後多設置一個數據源名稱primary
和secondary
來區分不一樣的數據源配置,這個前綴將在後續初始化數據源的時候用到。spring.datasource.secondary.jdbc-url
,而1.x版本使用spring.datasource.secondary.url
。若是你在配置的時候發生了這個報錯java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
,那麼就是這個配置項的問題。完成多數據源的配置信息以後,就來建立個配置類來加載這些配置信息,初始化數據源,以及初始化每一個數據源要用的JdbcTemplate。spring
因爲JPA的配置要比JdbcTemplate的負責不少,因此咱們將配置拆分一下來處理:sql
@Configuration public class DataSourceConfiguration { @Primary @Bean @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } }
能夠看到內容跟JdbcTemplate時候是如出一轍的。經過@ConfigurationProperties
能夠知道這兩個數據源分別加載了spring.datasource.primary.*
和spring.datasource.secondary.*
的配置。@Primary
註解指定了主數據源,就是當咱們不特別指定哪一個數據源的時候,就會使用這個Bean真正差別部分在下面的JPA配置上。數據庫
Primary數據源的JPA配置:springboot
@Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactoryPrimary", transactionManagerRef="transactionManagerPrimary", basePackages= { "com.didispace.chapter38.p" }) //設置Repository所在位置 public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map<String, Object> getVendorProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) { return builder .dataSource(primaryDataSource) .packages("com.didispace.chapter38.p") //設置實體類所在位置 .persistenceUnit("primaryPersistenceUnit") .properties(getVendorProperties()) .build(); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
Secondary數據源的JPA配置:app
@Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef="entityManagerFactorySecondary", transactionManagerRef="transactionManagerSecondary", basePackages= { "com.didispace.chapter38.s" }) //設置Repository所在位置 public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; private Map<String, Object> getVendorProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) { return builder .dataSource(secondaryDataSource) .packages("com.didispace.chapter38.s") //設置實體類所在位置 .persistenceUnit("secondaryPersistenceUnit") .properties(getVendorProperties()) .build(); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
說明與注意:spring-boot
@EnableJpaRepositories
中指定Repository的所在位置LocalContainerEntityManagerFactoryBean
建立的時候,指定Entity所在的位置完成了上面以後,咱們就能夠寫個測試類來嘗試一下上面的多數據源配置是否正確了,好比下面這樣:
@Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class Chapter38ApplicationTests { @Autowired private UserRepository userRepository; @Autowired private MessageRepository messageRepository; @Test public void test() throws Exception { userRepository.save(new User("aaa", 10)); userRepository.save(new User("bbb", 20)); userRepository.save(new User("ccc", 30)); userRepository.save(new User("ddd", 40)); userRepository.save(new User("eee", 50)); Assert.assertEquals(5, userRepository.findAll().size()); messageRepository.save(new Message("o1", "aaaaaaaaaa")); messageRepository.save(new Message("o2", "bbbbbbbbbb")); messageRepository.save(new Message("o3", "cccccccccc")); Assert.assertEquals(3, messageRepository.findAll().size()); } }
說明與注意:
本文的相關例子能夠查看下面倉庫中的chapter3-8
目錄:
若是您以爲本文不錯,歡迎Star支持,您的關注是我堅持的動力!
本文首發: Spring Boot 2.x基礎教程:Spring Data JPA的多數據源配置,轉載請註明出處。
歡迎關注個人公衆號:程序猿DD,得到獨家整理的學習資源和平常乾貨推送。
若是您對個人其餘專題內容感興趣,直達個人我的博客: didispace.com。