实际项目过程中我们很可能碰到项目的数据源不在同一个数据库实例下,这时就需要我们配置多数据源,这篇文章主要讲述如何配置双数据源,以此类推多数据源也是可以配置的。
正文
1.配置数据库信息
以下代码展示是在yml中配置,application.properties与application.yml类似,不再赘言。
- 特别注意使用的是jdbc-url不是url,否则你就会蛋疼的发现项目老是报出jdbc-url is required driverClassName,具体原因我也不太懂,后面如果懂得话会更新补充
spring:
# 主数据
primary:
datasource:
driver-class-name: oracle.jdbc.driver.OracleDriver
jdbc-url:
username:
password:
# 第二数据
secondary:
datasource:
driver-class-name: oracle.jdbc.driver.OracleDriver
jdbc-url:
username:
password:
2.配置生成相应datasource的类
@Configuration
public class DataSourceConfigure {
@Bean(name = "primaryDataSource")
//个人理解该注解主要用于表明优先性,当使用@Autowired时没有特殊标明的话,默认使用这个bean
@Primary
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix = "spring.primary.datasource")
public DataSource primaryDatasource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix = "spring.secondary.datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
3.配置实体工厂
- primary数据源:
/**
* 用于生成相应的jpa接口实现类,相当于传统意义上的dao接口实现类(2019-01-14 13:56)
*
* @author stone
* @version 1.0
* @since JDK 1.8
**/
@Configuration
//开启事务支持,关于JPA,JDBC都是通过实现接口PlatformTransactionManager实现事物管理的,前者实现类为JpaTransactionManager
@EnableTransactionManagement
//开启jpa存储库扫描
@EnableJpaRepositories(
//实体管理工厂引用名称
entityManagerFactoryRef = "entityManagerFactoryPrimary",
//事物管理工厂引用名称
transactionManagerRef = "transactionManagerPrimary",
//扫描位置(dao接口位置)
basePackages = {""}
)
public class PrimaryDataSourceConfigure {
//获得相应datasource
@Qualifier("primaryDataSource")
@Autowired
private DataSource primaryDataSource;
//配置EntityManager实体
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder){
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
//配置EntityManager实体工厂
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder){
return builder
.dataSource(primaryDataSource)
.properties(getVendorProperties(primaryDataSource))
//实体类位置
.packages("")
.persistenceUnit("primaryPersistenceUnit")
.build();
}
//注入jpa配置实体
@Autowired
private JpaProperties jpaProperties;
private Map<String, String> getVendorProperties(DataSource dataSource) {
//实现数据库的持久层支持
jpaProperties.determineDatabase(dataSource);
return jpaProperties.getProperties();
}
//实现事物管理接口
@Bean(name = "transactionManagerPrimary")
@Primary
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
- secondary数据源:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {""})
public class SecondaryDataSourceConfigure {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDS;
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDS)
.properties(getVendorProperties(secondaryDS))
.packages("")
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
jpaProperties.determineDatabase(dataSource);
return jpaProperties.getProperties();
}
}
4.实体类,jpa接口位置
- 由于数据源不同相应的jpa接口以及实体类最好分开用于区分