说明:
primary
、secondary
这一层级的配置primary
、secondary
只是一个名称,可以根据实际情况进行命名,比如在使用druid数据源时可以把secondary
改为druid
,也是可以的spring:
datasource:
# 主数据源
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/data_studio?charset=utf8mb4&useSSL=false&serverTimezone=UTC
username: ds
password: 12345678
# 辅助数据源
secondary:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/data_studio?charset=utf8mb4&useSSL=false&serverTimezone=UTC
username: ds
password: 12345678
jpa:
properties:
hibernate:
hbm2ddl:
# 只验证表结构,不修改
auto: validate
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
jdbc:
# 设置时区
time_zone: Asia/Shanghai
implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
# 无须打印SQL
show-sql: false
open-in-view: false
只使用一个数据源时,Spring Data JPA能够自动识别JPA配置,并且初始化数据源。但在多数据源的场景下,必须手工初始化数据源。
package cn.wesure.da.ds.manager.config;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* @author chriscchen
* @createtime 2021-02-05
*/
@Configuration
public class DataSourceConfig {
// 不少教程是把jpaProperties、hibernateProperties、getVendorProperties放到具体的JPA配置中,代码重复冗余。
// 可以把这两个属性、一个方法在这里自动注入来初始化,然后在对应的JPA配置中自动注入即可
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
// 自动注入时的对象名称
@Bean(name = "vendorProperties")
public Map getVendorProperties() {
return hibernateProperties
.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
// 主数据源,加上 @Primary。
@Primary
// 自动注入时的对象名称
@Bean(name = "primaryDataSource")
// 主数据源的配置项前缀
@ConfigurationProperties("spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
// 自动注入时的对象名称
@Bean(name = "secondaryDataSource")
// 辅助数据源的配置项前缀
@ConfigurationProperties("spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
JPA配置主要是告诉Spring Data JPA哪些Respository查询接口、domain模型类是属于哪个数据源
在类名上通过注释 @EnableJpaRepositories
中指定Repository所在的位置
在创建LocalContainerEntityManagerFactoryBean
时,指domain模型类所在的位置
Primary数据源
package cn.wesure.da.ds.manager.config;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author chriscchen
* @createtime 2021-02-05
*/
@SuppressWarnings("ConstantConditions")
@Configuration
@EnableTransactionManagement
// 指定Primary数据源Repository的包名
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"cn.wesure.da.ds.manager.repository.primary"})
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
// 自动注入在配置类中提供的初始化方法
@Autowired
@Qualifier("vendorProperties")
private Map vendorProperties;
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(
EntityManagerFactoryBuilder builder) {
// 指定模型类的包名
return builder
.dataSource(primaryDataSource)
.properties(vendorProperties)
.packages("cn.wesure.da.ds.manager.domain.primary")
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "transactionManagerPrimary")
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
package cn.wesure.da.ds.manager.config;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author chriscchen
* @createtime 2021-02-05
*/
@SuppressWarnings("ConstantConditions")
@Configuration
@EnableTransactionManagement
// 指定Secondary数据源Repository的包名
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= {"cn.wesure.da.ds.manager.repository.secondary"})
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
// 自动注入在配置类中提供的初始化方法
@Autowired
@Qualifier("vendorProperties")
private Map vendorProperties;
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (
EntityManagerFactoryBuilder builder) {
// 指定模型类的包名
return builder
.dataSource(secondaryDataSource)
.properties(vendorProperties)
.packages("cn.wesure.da.ds.manager.domain.secondary")
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
至此已经完成Spring Data JPA的多数据源配置,后续只须按照不同的包创建Repository
、domain
即可