Java後端愛上SpringBoot 第四節:SpringBoot多資料來源
阿新 • • 發佈:2019-01-01
Java後端愛上SpringBoot 第四節:SpringBoot多資料來源
PS:配置多資料來源這個事情是專案中用到的,之前也做過dome,但是做的時候又踩了幾個坑,因此要記錄一下。
配置一個Oracle資料庫
先貼一下pom.xml檔案:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns: xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</ artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.summit</groupId>
<artifactId>summit-tas</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SmartTAS</ name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.0.jre8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version><!--$NO-MVN-MAN-VER$ -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我們配置一個主資料來源:primary
application.yml配置如下:
spring:
datasource:
primary:
###運維庫
driver-class-name: oracle.jdbc.driver.OracleDriver
jdbc-url: jdbc:oracle:thin:@//127.0.0.1:1521/ORCL
username: oracle
password: oracle
###驗證連線有效性
test-while-idle: true
###獲取連線時候驗證,會影響效能
test-on-borrow: false
###在連線歸還到連線池時是否測試該連線
test-on-return: false
###空閒連接回收的時間間隔
time-between-eviction-runs-millis: 300000
###連線池空閒連線的有效時間 ,設定30分鐘
min-evictable-idle-time-millis: 1800000
###連線池配置
maximum-pool-size: 50
minIdle: 50
connection-timeout: 30000
max-lifetime: 1800000
新增一個DataSourcesConfig 用來配置資料來源的Bean
坑點一:
SpringBoot1.*的時候是spring.datasource.jdbcUrl,2.0的時候變成了spring.datasource.jdbc-url
import javax.sql.DataSource;
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;
/**
* 多資料來源配置
*
* @Title: DataSourcesConfig.java
* @Package com.summit.tas.cfg.db
* @Description: TODO
* @author hyn
* @date 2018年12月27日 下午3:43:53
* @version V1.0
*/
@Configuration
public class DataSourcesConfig {
@Bean(name = "primaryDataSource")
@Qualifier("primaryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
}
使用@Qualifier 來區分資料來源。
新增一個PrimaryConfig類:
package com.summit.tas.cfg.db;
import java.util.Properties;
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;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary", transactionManagerRef = "transactionManagerPrimary", basePackages = {
"com.summit.tas.primary.repository" })
//basePackages 為dao包,會自動掃面配置下面的包
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
/**
* 主庫jpa 例項管理器工廠配置
*/
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
//實體類的配置路徑
LocalContainerEntityManagerFactoryBean em = builder.dataSource(primaryDataSource).packages("com.summit.tas.primary.dto")
.build();
Properties properties = new Properties();
properties.setProperty("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
em.setJpaProperties(properties);
return em;
}
/**
* 主庫事務管理器配置
*/
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactoryPrimary(builder).getObject());
return txManager;
}
}
下面就可以進行增刪改查了。
配置一個SQLServer資料庫
再配一個SQLServer資料來源:
給application.yml新增以下配置:
sydn:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc-url: jdbc:sqlserver://127.0.0.1:1433;database=cqswssydn
username: sa
password: 123456
###驗證連線有效性
test-while-idle: true
###獲取連線時候驗證,會影響效能
test-on-borrow: false
###在連線歸還到連線池時是否測試該連線
test-on-return: false
###空閒連接回收的時間間隔
time-between-eviction-runs-millis: 300000
###連線池空閒連線的有效時間 ,設定30分鐘
min-evictable-idle-time-millis: 1800000
###連線池配置
maximum-pool-size: 20
minIdle: 20
connection-timeout: 30000
max-lifetime: 1800000
在DataSourcesConfig新增以下:
@Bean(name = "sydnDataSource")
@Qualifier("sydnDataSource")
@ConfigurationProperties(prefix = "spring.datasource.sydn")
public DataSource sydnDataSource() {
return DataSourceBuilder.create().build();
}
新增一個SydnConfig:
package com.summit.tas.cfg.db;
import java.util.Properties;
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;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactorySydn", transactionManagerRef = "transactionManagerSydn", basePackages = {
"com.summit.tas.sydn.repository" })
public class SydnConfig {
@Autowired
@Qualifier("sydnDataSource")
private DataSource sydnDataSource;
/**
* sydn jpa 例項管理器工廠配置
*/
@Bean(name = "entityManagerFactorySydn")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean em = builder.dataSource(sydnDataSource).packages("com.summit.tas.sydn.dto")
.build();
Properties properties = new Properties();
properties.setProperty("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
em.setJpaProperties(properties);
return em;
}
/**
* sydn 事務管理器配置
*/
@Bean(name = "transactionManagerSydn")
public PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactorySecondary(builder).getObject());
return txManager;
}
}
坑點二:
用sqlserver的時候不要用
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.6</version>
</dependency>
要用:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.1.0.jre8</version>
</dependency>
配置一個MySql資料庫
再配一個MySql資料來源:
給application.yml新增以下配置:
mysql:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/spring?useUnicode=true&characterEncoding=UTF-8&useSSL=false&autoReconnect=true&allowPublicKeyRetrieval=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
username: hyn
password: hyn1234
###驗證連線有效性
test-while-idle: true
###獲取連線時候驗證,會影響效能
test-on-borrow: false
###在連線歸還到連線池時是否測試該連線
test-on-return: false
###空閒連接回收的時間間隔
time-between-eviction-runs-millis: 300000
###連線池空閒連線的有效時間 ,設定30分鐘
min-evictable-idle-time-millis: 1800000
###連線池配置
maximum-pool-size: 20
minIdle: 20
connection-timeout: 30000
max-lifetime: 1800000
在DataSourcesConfig新增以下:
@Bean(name = "mysqlDataSource")
@Qualifier("mysqlDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mysql")
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}
新增一個MysqlConfig:
package com.summit.tas.cfg.db;
import java.util.Properties;
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;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryMysql", transactionManagerRef = "transactionManagerMysql", basePackages = {
"com.summit.tas.mysql.repository" })
public class MysqlConfig {
@Autowired
@Qualifier("mysqlDataSource")
private DataSource wdsDataSource;
/**
* mysql jpa 例項管理器工廠配置
*/
@Bean(name = "entityManagerFactoryWds")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean em = builder.dataSource(wdsDataSource).packages("com.summit.tas.mysql.dto")
.build();
Properties properties = new Properties();
properties.setProperty("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
em.setJpaProperties(properties);
return em;
}
/**
* mysql 事務管理器配置
*/
@Bean(name = "transactionManagerW