在项目中,多数据源的配置还是用的比较多的,现在就来介绍下springboot整合jpa实现多数据源配置
1.导入maven依赖:
<!--jpa依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
2.application.yml配置:
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss.SSS
time-zone: GMT+8
datasource:
primary: ###primary配置
url: jdbc:mysql://localhost:3306/seller?user=root&password=mysql0000&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
backup: ####backup配置
url: jdbc:mysql://localhost:3306/backupseller?user=root&password=mysql0000&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
driver-class-name: com.mysql.jdbc.Driver
3.数据源配置,包括DataSource配置,entityManagerFactory,以及transactionManager的配置,详见代码:
@Configuration
public class DataSourceAccessConfiguration {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private ObjectProvider<List<SchemaManagementProvider>> providers;
@Autowired
private ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy;
@Autowired
private ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy;
/**
* 主数据库连接配置
* @return
*/
@Bean
@Qualifier("primaryDataSource")
@ConfigurationProperties("spring.datasource.primary")
@Primary
public DataSource primaryDataSource(){
return DataSourceBuilder.create().build();
}
/**
* 备数据库连接配置
* @return
*/
@Qualifier("backupDataSource")
@Bean
@ConfigurationProperties("spring.datasource.backup")
public DataSource backupDataSource(){
return DataSourceBuilder.create().build();
}
/**
* 主 EntityManagerFactory配置
* @param builder
* @return
*/
@Bean
@Qualifier("primaryEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder){
return builder.dataSource(primaryDataSource())
.properties(getVendorProperties(primaryDataSource()))
.packages(OrderRepository.class) //扫描OrderRepository所在的包
.persistenceUnit("primary")
.build();
}
/**
* 主 TransactionManager配置 事务配置
* @param builder
* @return
*/
@Bean
@Qualifier("primaryTransactionManager")
@Primary
public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager(primaryEntityManagerFactory.getObject());
return transactionManager;
}
/**
* 备 EntityManagerFactory配置
* @param builder
* @return
*/
@Bean
@Qualifier("backupEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean backupEntityManagerFactory(EntityManagerFactoryBuilder builder){
return builder.dataSource(backupDataSource())
.properties(getVendorProperties(backupDataSource()))
.packages(VerifyOrderRepository.class) //扫描VerifyOrderRepository所在的包
.persistenceUnit("backup")
.build();
}
/**
* 备 TransactionManager配置 事务配置
* @param builder
* @return
*/
@Bean
@Qualifier("backupTransactionManager")
public PlatformTransactionManager backupTransactionManager(@Qualifier("backupEntityManagerFactory") LocalContainerEntityManagerFactoryBean backupEntityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager(backupEntityManagerFactory.getObject());
return transactionManager;
}
/**
* 配置hibernate的配置信息
* @param dataSource
* @return
*/
protected Map<String, Object> getVendorProperties(DataSource dataSource) {
Map<String, Object> vendorProperties = new LinkedHashMap<String, Object>();
String defaultDdlMode = new HibernateDefaultDdlAutoProvider(
providers.getIfAvailable(Collections::emptyList))
.getDefaultDdlAuto(dataSource);
vendorProperties.putAll(jpaProperties.getHibernateProperties(
new HibernateSettings().ddlAuto(defaultDdlMode).physicalNamingStrategy(physicalNamingStrategy.getIfAvailable())
.implicitNamingStrategy(implicitNamingStrategy.getIfAvailable())
));
return vendorProperties;
}
class HibernateDefaultDdlAutoProvider implements SchemaManagementProvider {
private final List<SchemaManagementProvider> providers;
HibernateDefaultDdlAutoProvider(List<SchemaManagementProvider> providers) {
this.providers = providers;
}
public String getDefaultDdlAuto(DataSource dataSource) {
if (!EmbeddedDatabaseConnection.isEmbedded(dataSource)) {
return "none";
} else {
SchemaManagement schemaManagement = this.getSchemaManagement(dataSource);
return SchemaManagement.MANAGED.equals(schemaManagement) ? "none" : "create-drop";
}
}
public SchemaManagement getSchemaManagement(DataSource dataSource) {
Iterator var2 = this.providers.iterator();
SchemaManagement schemaManagement;
do {
if (!var2.hasNext()) {
return SchemaManagement.UNMANAGED;
}
SchemaManagementProvider provider = (SchemaManagementProvider)var2.next();
schemaManagement = provider.getSchemaManagement(dataSource);
} while(!SchemaManagement.MANAGED.equals(schemaManagement));
return schemaManagement;
}
}
}
repository的目录结构如下:
基于上面的基本配置,即可完成多数据源的配置。。。。
另: 实现读写分离,只需要在别的数据源下创建接口,实现主数据库的repository接口,即可实现读写分离,这也是最简单的方式。
上述接口BackUpOrderRepository实现主库的OrderRepository接口,但是却在从库的包下,这样,具备主库的功能,但是却操作的是从库,这样就可以实现读写分离,至于数据数主库,从库数据一致性问题,这里不做讨论,mycat,otter可以解决这些问题,感兴趣的可以去看看,这里就不做详细的介绍了。
至此,springBoot整合jpa多数据源,读写分离,就介绍完毕了。。。