SpringBoot+Jpa+PostgreSQL配置多数据源
- 使用的持久化框架为JPA,所以数据源也是基于JPA。采用的是SpringBoot2 + SpringDataJPA + postgresql + 双数据源!
- 一:多数据源的使用场景
- 二:application.yml中配置
- 三、读取application.yml配置的两个数据源,并将其注入到Spring的IOC容器中
- 四、以类的方式配置两个数据源
- 五:注意点
使用的持久化框架为JPA,所以数据源也是基于JPA。采用的是SpringBoot2 + SpringDataJPA + postgresql + 双数据源!
一:多数据源的使用场景
1、主从库分离(数据库读写分离)
2、数据迁移
3、系统版本升级,数据库升级到另外一款
二:application.yml中配置
**spring:
jpa:
hibernate:
ddl-auto: create
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
open-in-view: true
show-sql: true
generate-ddl: true
#多数据源配置
datasource: #database
primary: # 业务信息数据库
url: jdbc:postgresql://192.168.4.240:5432/cmcci
username: postgres
password: postgres
driver-class-name: org.postgresql.Driver
secondary: # 空间地图数据库
url: jdbc:postgresql://211.149.141.72:5432/xcu
username: postgres
password: lqkj!@#456
driver-class-name: org.postgresql.Driver**
注:配置文件中需要指定两个数据源,如果需要多个数据源,像上面一样的配置,这里在配置的时候是没有自动提示的,因为这是我们自定义的,需要在程序中动态读取
三、读取application.yml配置的两个数据源,并将其注入到Spring的IOC容器中
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Qualifier("primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
注解解释:
@Configuration:SpringBoot启动将该类作为配置类,同配置文件一起加载
@Bean:将该实体注入到IOC容器中
@Qualifier:指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功
@Primary:指定主数据源
@ConfigurationProperties:将配置文件中的数据源读取进到方法中,进行build
四、以类的方式配置两个数据源
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"com.you07.booksearch.service.primary"})// 指定该数据源操作的DAO接口包
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@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)
.properties(getVendorProperties())
.packages("com.you07.booksearch.entity.primary") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map getVendorProperties() {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
properties.put("hibernate.ddl-auto",
"create");
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
return properties;
}
@Autowired
private Environment env;
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
(2)次数据源
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {"com.you07.booksearch.service.secondary"}) //设置DAO接口层所在包位置
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@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)
.properties(getVendorProperties())
.packages("com.you07.booksearch.entity.secondary") //设置实体类所在包的位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map getVendorProperties() {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.ddl-auto",
env.getProperty("update"));
properties.put("hibernate.dialect",
env.getProperty("hibernate.dialect"));
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
return properties;
}
@Autowired
private Environment env;
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
这两个类主要配置每个数据源,包括事务管理器、以及实体管理器等配置。
注:必须要指定DAO接口所在的包以及实体类所在的包。每个数据源主要操作它指定的资源(DAO接口CURD、实体类
五:注意点
1、SpringBoot启动类必须关闭 --程序启动加载的仓库(@EnableJpaRepositories),因为在数据源配置类中已经开启了。如果没有去掉,程序会跑不起来
@SpringBootApplication
@EnableTransactionManagement
//@EnableJpaRepositories(basePackages = {""})
public class BookSearchXcuApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(BookSearchXcuApplication.class);
}
public static void main(String[] args) {
new SpringApplicationBuilder(BookSearchXcuApplication.class).web(true).run(args);
}
}
2、如果需要对数据源连接的表进行DDL(正向生成表、程序启动动态更新表),需要在PrimaryConfig类中 / SecondaryConfig类中的getVendorProperties()方法中进行手动设置(上面我都已设置好了!)