前言
springboot配置雙資料源時要特别注意springboot的版本号,各個版本号不一樣,寫法也不一樣.我用的是1.5.x,具體寫法如下:
項目結構
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLwMmeNdXVU1UNNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLwQTN4ETMzQTMzATOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
pom檔案
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 資料資源相關 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- lombok插件 實體注解省略get set -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Swagger的配置依賴包 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
</dependencies>
yml檔案
spring:
datasource:
primary: # 主資料源
# mysql 連接配接配置
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&useSSL=false
username: # 使用者名
password: # 密碼
secondary: # 次資料源
# mysql 連接配接配置
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8&useSSL=false
username: # 使用者名
password: # 密碼
jpa:
database: mysql
hibernate:
ddl-auto: update # 反向生成
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy #jpa命名政策
show-sql: false # 顯示sql
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
# 檔案大小
http:
multipart:
max-file-size: 10Mb # 單個檔案不超過10M
max-request-size: 100Mb # 請求檔案總大小不超過100M
#檔案位置
fileProps:
filePath: ./target/upload
##################### Spring Boot WEB start #####################
# Server HTTP port.
server:
port: 9004 # 端口
tomcat:
uri-encoding: utf-8
雙資料源配置檔案
1.DataSourceConfig 檔案
package com.test.testdemo.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* @Desc 讀取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();
}
}
2.配置主要資料源檔案
package com.test.testdemo.config;
import java.util.HashMap;
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.autoconfigure.orm.jpa.JpaProperties;
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.orm.jpa.vendor.Database;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Desc 配置主要資料源
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"com.test.testdemo.repository.primary"}) // 指定該資料源操作的DAO接口包
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Autowired
private JpaProperties jpaProperties;
@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(primaryDataSource))
.packages("com.test.testdemo.entity.primary") //設定實體類所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
jpaProperties.setDatabase(Database.MYSQL);
Map<String,String> map = new HashMap<>();
map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
map.put("hibernate.ddl-auto", "update");
map.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
jpaProperties.setProperties(map);
return jpaProperties.getHibernateProperties(dataSource);
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
3.配置第二個資料源檔案
package com.test.testdemo.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.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.orm.jpa.vendor.Database;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* @Desc 配置第二個資料源
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {"com.test.testdemo.repository.secondary"})
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Autowired
private JpaProperties jpaProperties;
@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.test.testdemo.entity.secondary") //設定實體類所在包的位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
/**
* 對資料源連接配接的表進行DDL(正向生成表、程式啟動動态更新表)
*
* @return
*/
private Map<String, String> getVendorProperties(DataSource dataSource) {
jpaProperties.setDatabase(Database.MYSQL);
Map<String, String> map = new HashMap<>();
map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");//mysql方言
map.put("hibernate.hbm2ddl.auto", "update");//反向生成
map.put("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl");
jpaProperties.setProperties(map);
return jpaProperties.getHibernateProperties(dataSource);
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
entity類
package com.test.testdemo.entity.primary;
import com.test.testdemo.base.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.math.BigDecimal;
/**
* 描述:檔案上傳下載下傳(主資料源)
*/
@Table(
name = "Document"
)
@Entity
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Document implements BaseEntity {
@Id
@GeneratedValue
private Integer id;
@Column(columnDefinition = "varchar(100) default ''")
private String name;//檔案名
@Column(columnDefinition = "varchar(100) default ''")
private String path;//檔案路徑
@Column(columnDefinition = "varchar(20) default ''")
private String fileType;//檔案類型
@Column(columnDefinition = "decimal(10,0) default 0")
private BigDecimal fileSize;//檔案大小
@Column(columnDefinition = "int default 0")
private Integer downloadTimes;//下載下傳次數
@Column(columnDefinition = "varchar(20) default ''")
private String creatorName;//建立人
}
第二個資料源實體類
package com.test.testdemo.entity.secondary;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
/**
* @Desc 學生實體類
*/
@Table(
name = "Student"
)
@Entity
@Getter
@Setter
@DynamicInsert//新增時空字段不去插入values
@DynamicUpdate//隻跟新變化的字段,結合merge方法使用
@JsonInclude(JsonInclude.Include.NON_NULL)
@EntityListeners({AuditingEntityListener.class})
@JsonIgnoreProperties({"modifier", "modifyDate"})
public class Student {
@Id
@GeneratedValue
private Integer id;
@Column(columnDefinition = "varchar(20) default ''")
private String name;
@Column(columnDefinition = "int default 0")
private Integer age;
}
dao層
package com.test.testdemo.repository.primary;
import com.test.testdemo.entity.primary.Document;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* 描述:檔案管理(主資料源)
*/
public interface DocumentRepository extends CrudRepository<Document, Integer> {
Integer deleteAllByIdIn(List<Integer> ids);
}
第二個資料源dao
package com.test.testdemo.repository.secondary;
import com.test.testdemo.entity.secondary.Student;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* @Desc 第二個資料源
*/
public interface StudentRepository extends CrudRepository<Student, Integer> {
Integer deleteAllByIdIn(List<Integer> ids);
}
這是配置雙資料源主要代碼,其他跟普通邏輯代碼都跟單資料源一樣,這裡就不在重複講述了,如果有什麼不懂的可以與我聯系!