前言:我們在單資料源的情況下,springboot配置是很簡單的,隻需要導入相對應的
包以及在配置檔案配置連接配接參數即可。但是往往随着業務的發展,我們通常會進行數
據庫拆分以及比較老的系統需要內建時使用的資料庫不一樣,這個時候就需要配置多資料源的配置。參考網上各文章整理後配置好的多資料源。
一、項目依賴pom.xml配置
springboot版本為2.2.0,以下maven依賴包括sqlserver、mysql、jpa(按需求添加)
com.microsoft.sqlserver
mssql-jdbc
runtime
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-data-jpa
二、application.yml配置檔案配置
同時連接配接兩個資料庫,配置如下
server:
port: 8888
tomcat:
uri-encoding: utf-8
servlet:
context-path: /airQuality
session:
timeout: 30m
spring:
jpa:
database: MYSQL
show-sql: true
hibernate:
ddl-auto: update
second-dialect: org.hibernate.dialect.MySQL5Dialect
main-dialect: org.hibernate.dialect.SQLServer2008Dialect
datasource:
second:
# mysql資料源配置
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3006/bigdata_ecology_integrated_management?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
database: mysql
configuration:
maximum-pool-size: 30
dbcp2:
max-idle: 10
max-wait-millis: 10000
min-idle: 5
initial-size: 5
#sqlserver資料源配置
main:
url: jdbc:sqlserver://localhost:11433;DatabaseName=AQI
username: U_AQI
password: [email protected]
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
database: sql_server
configuration:
maximum-pool-size: 30
三、配置雙資料源主要代碼
1.建立主從資料源DataSourceConfig配置類
package com.eco.power.air.airquality.config;
import org.springframework.beans.factory.annotation.Qualifier;
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;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Primary
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix = "datasource.main")
public DataSource primaryDatasource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix = "datasource.second")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
2.主資料源的配置
package com.eco.power.air.airquality.config;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
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;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",//配置連接配接工廠 entityManagerFactory
transactionManagerRef = "transactionManagerPrimary", //配置 事物管理器 transactionManager
basePackages = {"com.eco.power.air.airquality.repositoryPrimary"}//設定持久層所在位置
)
public class PrimaryConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("primaryDataSource")
// 自動注入配置好的資料源
private DataSource primaryDataSource;
@Value("${spring.jpa.hibernate.main-dialect}")
// 擷取對應的資料庫方言
private String primaryDialect;
@Bean(name = "entityManagerFactoryPrimary")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
//設定資料源
.dataSource(primaryDataSource)
//設定資料源屬性
.properties(getVendorProperties(primaryDataSource))
//設定實體類所在位置.掃描所有帶有 @Entity 注解的類
.packages("com.eco.power.air.airquality.entityPrimary")
// Spring會将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之後,
// Repository就能用它來建立 EntityManager 了,然後 EntityManager 就可以針對資料庫執行操作
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map getVendorProperties(DataSource dataSource) {
Map map = new HashMap<>();
// 設定對應的資料庫方言
map.put("hibernate.dialect",primaryDialect);
jpaProperties.setProperties(map);
return jpaProperties.getProperties();
}
@Bean(name = "transactionManagerPrimary")
@Primary
PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
3.從資料源的配置
package com.eco.power.air.airquality.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Value;
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;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.eco.power.air.airquality.repositorySecondary" })
public class SecondaryConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Value("${spring.jpa.hibernate.second-dialect}")
private String secondaryDialect;
@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(secondaryDataSource))
.packages("com.eco.power.air.airquality.entitySecondary")
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
private Map getVendorProperties(DataSource dataSource) {
Map map = new HashMap<>();
map.put("hibernate.dialect",secondaryDialect);
jpaProperties.setProperties(map);
return jpaProperties.getProperties();
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
完成了以上配置之後,
主資料源的實體位于:com.eco.power.air.airquality.entityPrimary
主資料源的資料通路對象位于:com.eco.power.air.airquality.repositoryPrimary
第二資料源的實體位于: com.eco.power.air.airquality.entitySecondary
第二資料源的資料通路接口位于:com.eco.power.air.airquality.repositoryPrimary
分别在這些package下建立各自的實體和資料通路接口!
至此多資料源配置完成,此方法也适用于其他資料庫配置,隻需修改application.yml中的資料源配置即可。