前言
在实际的开发中,大多数时候一个项目用到的数据库源都只有一个,但是难免遇到特例,如果遇到了同个项目需要连接两个或更多数据源我们该怎么呢?
本文带你了解 Spring Boot 配置多数据源。
准备工作
准备数据库,我这里使用同一个
Mysql
中的两个不同的数据库,并且分别在两个数据库中创建了一张数据表primary_table表结构
secondary_table表结构
主要代码
引入依赖
1 | <dependencies> |
实体类
PrimaryTable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.imxushuai.entity.primary;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
public class PrimaryTable {
private Long id;
private String username;
private String password;
private String p;
}SecondaryTable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.imxushuai.entity.secondary;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
public class SecondaryTable {
private Long id;
private String username;
private String password;
private String s;
}
我这里使用lombok
,不需要写get
和set
方法,使用@Data
注解在编译时会自动生成。
编写配置文件
由于有多个数据源,所以这里在配置文件里,我们需要配置多个数据源信息。(本例中采用的是两个Mysql数据库,若你想连接不同的数据库只需要修改jdbc-url
以及驱动类)
1 | spring: |
注意:
Spring Boot 2.x
中数据库URL的配置字段为:jdbc-url
Spring Boot 1.x
中数据库URL的配置字段为:url
配置双数据源
1 | package com.imxushuai.config; |
- 多个数据源,必须使用
@Primary
注解指定一个主数据源
配置多个数据源的连接信息
由于Spring Boot 1.x
和Spring Boot 2.x
配置多数据源有一些差别,所以这里我分为1.x
和2.x
两块,具体用哪部分根据Spring Boot
版本决定。
准确的来说是:2.0.6
版本以后和之前的版本有较大区别。
注意:两个数据源的实体类和Repository需要分包存放,参考下面的包结构
1.x
配置
Primary
数据源1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63package com.ensat.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.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.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages= { "com.imxushuai.repository.primary" }) //设置Repository所在位置
public class PrimaryConfig {
"primaryDataSource") (
private DataSource primaryDataSource;
private JpaProperties jpaProperties;
"entityManagerPrimary") (name =
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
"entityManagerFactoryPrimary") (name =
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)
.properties(getVendorProperties(primaryDataSource))
.packages("com.imxushuai.entity.primary") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
"transactionManagerPrimary") (name =
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}配置
Secondary
数据源1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59package com.ensat.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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.imxushuai.repository.secondary" }) //设置Repository所在位置
public class SecondaryConfig {
"secondaryDataSource") (
private DataSource secondaryDataSource;
private JpaProperties jpaProperties;
"entityManagerSecondary") (name =
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
"entityManagerFactorySecondary") (name =
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource)
.properties(getVendorProperties(secondaryDataSource))
.packages("com.imxushuai.entity.secondary") //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
"transactionManagerSecondary") (name =
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
2.x
配置
Primary
数据源1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68package com.imxushuai.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.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.JpaRepository;
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.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages= { "com.imxushuai.repository.primary" }) //设置Repository所在位置
public class PrimaryConfig {
"primaryDataSource") (
private DataSource primaryDataSource;
private HibernateProperties hibernateProperties;
private JpaProperties jpaProperties;
"entityManagerPrimary") (name =
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
"entityManagerFactoryPrimary") (name =
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
// 在2.0.6以上版本,jpaProperties中没有直接获取HibernateProperties的方法了
Map<String, Object> properties = hibernateProperties
.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
return builder
.dataSource(primaryDataSource)
.properties(properties)
.packages("com.imxushuai.entity.primary") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
"transactionManagerPrimary") (name =
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}配置
Secondary
数据源1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62package com.imxushuai.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.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;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.imxushuai.repository.secondary" }) //设置Repository所在位置
public class SecondaryConfig {
"secondaryDataSource") (
private DataSource secondaryDataSource;
private HibernateProperties hibernateProperties;
private JpaProperties jpaProperties;
"entityManagerSecondary") (name =
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
"entityManagerFactorySecondary") (name =
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
// 在2.x中jpaProperties中没有直接获取HibernateProperties的方法了
Map<String, Object> properties = hibernateProperties
.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
return builder
.dataSource(secondaryDataSource)
.properties(properties)
.packages("com.imxushuai.entity.secondary") //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
"transactionManagerSecondary") (name =
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
Repository
这个没什么说的,继承CrudRepository
1 | package com.imxushuai.repository.primary; |
1 | package com.imxushuai.repository.secondary; |
测试
编写测试类
1 | package com.imxushuai; |
运行结果:
新增成功并且成功查询到数据。
我这里的截图是Spring Boot 2.x
,findById
出来结果使用Optional
包裹的。
代码获取
Github: