之前在介绍使用Spring-data-jpa时,都使用了单数据源。在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties
文件中配置连接参数即可。但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源,下面基于Spring-data-jpa的例子介绍多数据源的配置方式。
一、项目结构图(总体浏览下最终完成后的建包样式)
具体展开图(总体浏览下最终完成后的建包样式):
二、创建一个Spring配置类,定义两个DataSource用来读取application.properties中
的不同配置。如下例子中,主数据源配置为spring.datasource.primary
开头的配置,第二数据源配置为spring.datasource.secondary
开头的配置。
【DataSourceConfig】
1 package com.didispace.config; 2 3 import org.springframework.beans.factory.annotation.Qualifier; 4 import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 5 import org.springframework.boot.context.properties.ConfigurationProperties; 6 import org.springframework.context.annotation.Bean; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.Primary; 9 10 import javax.sql.DataSource; 11 12 @Configuration 13 public class DataSourceConfig { 14 15 @Bean(name = "primaryDataSource") 16 @Qualifier("primaryDataSource") 17 @Primary 18 @ConfigurationProperties(prefix="spring.datasource.primary") 19 public DataSource primaryDataSource() { 20 return DataSourceBuilder.create().build(); 21 } 22 23 @Bean(name = "secondaryDataSource") 24 @Qualifier("secondaryDataSource") 25 @ConfigurationProperties(prefix="spring.datasource.secondary") 26 public DataSource secondaryDataSource() { 27 return DataSourceBuilder.create().build(); 28 } 29 30 }
对应的application.properties
配置如下:
1 spring.datasource.primary.url=jdbc:mysql://localhost:3306/scott 2 spring.datasource.primary.username=root 3 spring.datasource.primary.password=root 4 spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver 5 6 spring.datasource.secondary.url=jdbc:mysql://localhost:3306/scott_2 7 spring.datasource.secondary.username=root 8 spring.datasource.secondary.password=root 9 spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver 10 11 #display sql in console,设置将每一条jpa指令都打印在控制台中 12 spring.jpa.show-sql=true 13 14 spring.main.allow-bean-definition-overriding=true
注意:
关于异常提示:dataSource或dataSourceClassName或jdbcUrl是必需的
解决方案:
将:
spring.datasource.primary.url=jdbc:mysql://IP地址/drp_db
修改为:
spring.datasource.primary.jdbc-url=jdbc:mysql://IP地址/drp_db
三、数据源的JPA配置(几个数据源,几个相应名称匹配的配置,自己理解,后期尽量改成批量方式)------注意注释的部分
【PrimaryConfig】
1 package com.didispace.config; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Qualifier; 5 import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; 6 import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 10 import org.springframework.orm.jpa.JpaTransactionManager; 11 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 12 import org.springframework.transaction.PlatformTransactionManager; 13 import org.springframework.transaction.annotation.EnableTransactionManagement; 14 15 import javax.persistence.EntityManager; 16 import javax.sql.DataSource; 17 import java.util.Map; 18 19 @Configuration 20 @EnableTransactionManagement 21 @EnableJpaRepositories( 22 entityManagerFactoryRef = "entityManagerFactoryPrimary", 23 transactionManagerRef = "transactionManagerPrimary", 24 basePackages = {"com.didispace.repository.primary"}) //设置Repository所在位置 25 public class PrimaryConfig { 26 27 @Autowired 28 @Qualifier("primaryDataSource") 29 private DataSource primaryDataSource; 30 31 @Bean(name = "entityManagerPrimary") 32 public EntityManager entityManager(EntityManagerFactoryBuilder builder) { 33 return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); 34 } 35 36 @Bean(name = "entityManagerFactoryPrimary") 37 public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) { 38 return builder 39 .dataSource(primaryDataSource) 40 .properties(getVendorProperties(primaryDataSource)) 41 .packages("com.didispace.entity.primary") //设置实体类所在位置 42 .persistenceUnit("primaryPersistenceUnit") 43 .build(); 44 } 45 46 @Autowired 47 private JpaProperties jpaProperties; 48 49 private Map<String, String> getVendorProperties(DataSource dataSource) { 50 return jpaProperties.getHibernateProperties(dataSource); 51 } 52 53 @Bean(name = "transactionManagerPrimary") 54 public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { 55 return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); 56 } 57 58 }
【SecondaryConfig】
1 package com.didispace.config; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Qualifier; 5 import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; 6 import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 10 import org.springframework.orm.jpa.JpaTransactionManager; 11 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 12 import org.springframework.transaction.PlatformTransactionManager; 13 import org.springframework.transaction.annotation.EnableTransactionManagement; 14 15 import javax.persistence.EntityManager; 16 import javax.sql.DataSource; 17 import java.util.Map; 18 19 @Configuration 20 @EnableTransactionManagement 21 @EnableJpaRepositories( 22 entityManagerFactoryRef = "entityManagerFactorySecondary", 23 transactionManagerRef = "transactionManagerSecondary", 24 basePackages = {"com.didispace.repository.secondary"}) //设置Repository所在位置 25 public class SecondaryConfig { 26 27 @Autowired 28 @Qualifier("secondaryDataSource") 29 private DataSource secondaryDataSource; 30 31 @Bean(name = "entityManagerSecondary") 32 public EntityManager entityManager(EntityManagerFactoryBuilder builder) { 33 return entityManagerFactorySecondary(builder).getObject().createEntityManager(); 34 } 35 36 @Bean(name = "entityManagerFactorySecondary") 37 public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) { 38 return builder 39 .dataSource(secondaryDataSource) 40 .properties(getVendorProperties(secondaryDataSource)) 41 .packages("com.didispace.entity.secondary") //设置实体类所在位置 42 .persistenceUnit("secondaryPersistenceUnit") 43 .build(); 44 } 45 46 @Autowired 47 private JpaProperties jpaProperties; 48 49 private Map<String, String> getVendorProperties(DataSource dataSource) { 50 return jpaProperties.getHibernateProperties(dataSource); 51 } 52 53 @Bean(name = "transactionManagerSecondary") 54 PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { 55 return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); 56 } 57 58 }
四、最后,分别在这两个包下创建各自的实体和数据访问接口
测试结果:
1 package com.didispace; 2 3 import com.didispace.entity.secondary.Salgrade; 4 import com.didispace.repository.secondary.SalgradeRepository; 5 import com.didispace.entity.primary.Dept; 6 import com.didispace.repository.primary.DeptRepository; 7 import org.junit.Before; 8 import org.junit.Test; 9 import org.junit.runner.RunWith; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.boot.test.SpringApplicationConfiguration; 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13 14 import java.util.Iterator; 15 import java.util.List; 16 17 18 @RunWith(SpringJUnit4ClassRunner.class) 19 @SpringApplicationConfiguration(Application.class) 20 public class ApplicationTests { 21 22 @Autowired 23 private DeptRepository deptRepository; 24 @Autowired 25 private SalgradeRepository salgradeRepository; 26 27 @Before 28 public void setUp() { 29 } 30 31 @Test 32 public void test() throws Exception { 33 34 35 System.out.println("--- --- --- 结果如下 --- --- ---"); 36 System.out.println("【数据库scott】"); 37 List<Dept> ans = deptRepository.findByDname("FILL"); 38 Iterator<Dept> it = ans.iterator(); 39 while(it.hasNext()){ 40 Dept d = it.next(); 41 System.out.println(d); 42 43 } 44 45 System.out.println("--- --- --- --- --- --- --- --- "); 46 System.out.println("【数据库scott_2】"); 47 Salgrade grade = salgradeRepository.findByGrade(1); 48 System.out.println(grade); 49 } 50 51 52 }
原文:https://www.cnblogs.com/tubeWang/p/11633913.html