Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题。在 Spring Boot 整合JbdcTemplate 多数据源、Spring Boot 整合 MyBatis 多数据源以及 Spring Boot 整合 Jpa 多数据源这三个知识点中,整合 Jpa 多数据源算是最复杂的一种,也是很多人在配置时最容易出错的一种。本文大伙就跟着松哥的教程,一步一步整合 Jpa 多数据源。
工程创建
首先是创建一个 Spring Boot 工程,创建时添加基本的 Web、Jpa 以及 MySQL 依赖,如下:

创建完成后,添加 Druid 依赖,这里和前文的要求一样,要使用专为 Spring Boot 打造的 Druid,大伙可能发现了,如果整合多数据源一定要使用这个依赖,因为这个依赖中才有 DruidDataSourceBuilder,最后还要记得锁定数据库依赖的版本,因为可能大部分人用的还是 5.x 的 MySQL 而不是 8.x。完整依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.28</version>
<scope>runtime</scope>
</dependency>
如此之后,工程就创建成功了。
基本配置
在基本配置中,我们首先来配置多数据源基本信息以及 DataSource,首先在 application.properties 中添加如下配置信息:
# 数据源一
spring.datasource.one.username=root
spring.datasource.one.password=root
spring.datasource.one.url=jdbc:mysql:///test01?useUnicode=true&characterEncoding=UTF-8
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
# 数据源二
spring.datasource.two.username=root
spring.datasource.two.password=root
spring.datasource.two.url=jdbc:mysql:///test02?useUnicode=true&characterEncoding=UTF-8
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
# Jpa配置
spring.jpa.properties.database=mysql
spring.jpa.properties.show-sql=true
spring.jpa.properties.database-platform=mysql
spring.jpa.properties.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
这里 Jpa 的配置和上文相比 key 中多了 properties,多数据源的配置和前文一致,然后接下来配置两个 DataSource,如下:
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
@Primary
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
这里的配置和前文的多数据源配置基本一致,但是注意多了一个在 Spring 中使用较少的注解 @Primary,这个注解一定不能少,否则在项目启动时会出错,@Primary 表示当某一个类存在多个实例时,优先使用哪个实例。
好了,这样,DataSource 就有了。
多数据源配置
接下来配置 Jpa 的基本信息,这里两个数据源,我分别在两个类中来配置,先来看第一个配置:
@Configuration
@EnableJpaRepositories(basePackages = "org.javaboy.jpa.dao",entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanOne",transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {
@Autowired
@Qualifier(value = "dsOne")
DataSource dsOne;
@Autowired
JpaProperties jpaProperties;
@Bean
@Primary
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsOne)
.packages("org.javaboy.jpa.model")
.properties(jpaProperties.getProperties())
.persistenceUnit("pu1")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryBeanOne = localContainerEntityManagerFactoryBeanOne(builder);
return new JpaTransactionManager(factoryBeanOne.getObject());
}
}
首先这里注入 dsOne,再注入 JpaProperties,JpaProperties 是系统提供的一个实例,里边的数据就是我们在 application.properties 中配置的 jpa 相关的配置。然后我们提供两个 Bean,分别是 LocalContainerEntityManagerFactoryBean 和 PlatformTransactionManager 事务管理器,不同于 MyBatis 和 JdbcTemplate,在 Jpa 中,事务一定要配置。在提供 LocalContainerEntityManagerFactoryBean 的时候,需要指定 packages,这里的 packages 指定的包就是这个数据源对应的实体类所在的位置,另外在这里配置类上通过 @EnableJpaRepositories 注解指定 dao 所在的位置,以及 LocalContainerEntityManagerFactoryBean 和 PlatformTransactionManager 分别对应的引用的名字。
好了,这样第一个就配置好了,第二个基本和这个类似,主要有几个不同点:
- dao 的位置不同
- persistenceUnit 不同
- 相关 bean 的名称不同
注意实体类可以共用。
代码如下:
@Configuration
@EnableJpaRepositories(basePackages = "org.javaboy.jpa.dao2",entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanTwo",transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {
@Autowired
@Qualifier(value = "dsTwo")
DataSource dsTwo;
@Autowired
JpaProperties jpaProperties;
@Bean
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsTwo)
.packages("org.javaboy.jpa.model")
.properties(jpaProperties.getProperties())
.persistenceUnit("pu2")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryBeanTwo = localContainerEntityManagerFactoryBeanTwo(builder);
return new JpaTransactionManager(factoryBeanTwo.getObject());
}
}
接下来,在对应位置分别提供相关的实体类和 dao 即可,数据源一的 dao 如下:
package org.javaboy.jpa.dao;
public interface UserDao extends JpaRepository<User,Integer> {
List<User> getUserByAddressEqualsAndIdLessThanEqual(String address, Integer id);
@Query(value = "select * from t_user where id=(select max(id) from t_user)",nativeQuery = true)
User maxIdUser();
}
数据源二的 dao 如下:
package org.javaboy.jpa.dao2;
public interface UserDao2 extends JpaRepository<User,Integer> {
List<User> getUserByAddressEqualsAndIdLessThanEqual(String address, Integer id);
@Query(value = "select * from t_user where id=(select max(id) from t_user)",nativeQuery = true)
User maxIdUser();
}
共同的实体类如下:
package org.javaboy.jpa.model;
@Entity(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String username;
private String address;
//省略getter/setter
}
到此,所有的配置就算完成了,接下来就可以在 Service 中注入不同的 UserDao,不同的 UserDao 操作不同的数据源。
其实整合 Jpa 多数据源也不算难,就是有几个细节问题,这些细节问题解决,其实前面介绍的其他多数据源整个都差不多。
好了,本文就先介绍到这里。
相关案例已经上传到 GitHub,欢迎小伙伴们们下载:https://github.com/lenve/javaboy-code-samples
扫码关注松哥,公众号后台回复 2TB,获取松哥独家 超2TB 免费 Java 学习干货

Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源的更多相关文章
- Spring Boot2 系列教程(二十六)Spring Boot 整合 Redis
在 Redis 出现之前,我们的缓存框架各种各样,有了 Redis ,缓存方案基本上都统一了,关于 Redis,松哥之前有一个系列教程,尚不了解 Redis 的小伙伴可以参考这个教程: Redis 教 ...
- Spring Boot2 系列教程(二十八)Spring Boot 整合 Session 共享
这篇文章是松哥的原创,但是在第一次发布的时候,忘了标记原创,结果被好多号转发,导致我后来整理的时候自己没法标记原创了.写了几百篇原创技术干货了,有一两篇忘记标记原创进而造成的一点点小小损失也能接受,不 ...
- Spring Boot2 系列教程(二十四)Spring Boot 整合 Jpa
Spring Boot 中的数据持久化方案前面给大伙介绍了两种了,一个是 JdbcTemplate,还有一个 MyBatis,JdbcTemplate 配置简单,使用也简单,但是功能也非常有限,MyB ...
- Spring Boot2 系列教程(二十九)Spring Boot 整合 Redis
经过 Spring Boot 的整合封装与自动化配置,在 Spring Boot 中整合Redis 已经变得非常容易了,开发者只需要引入 Spring Data Redis 依赖,然后简单配下 red ...
- Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...
- Spring Boot2 系列教程(二十三)理解 Spring Data Jpa
有很多读者留言希望松哥能好好聊聊 Spring Data Jpa! 其实这个话题松哥以前零零散散的介绍过,在我的书里也有介绍过,但是在公众号中还没和大伙聊过,因此本文就和大家来仔细聊聊 Spring ...
- Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源
关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...
- Spring Boot2 系列教程(三十)Spring Boot 整合 Ehcache
用惯了 Redis ,很多人已经忘记了还有另一个缓存方案 Ehcache ,是的,在 Redis 一统江湖的时代,Ehcache 渐渐有点没落了,不过,我们还是有必要了解下 Ehcache ,在有的场 ...
- Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇
Spring cloud系列教程第十篇- Spring cloud整合Eureka总结篇 本文主要内容: 1:spring cloud整合Eureka总结 本文是由凯哥(凯哥Java:kagejava ...
随机推荐
- [BZOJ1076] 奖励关
Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的 ...
- Ubuntu使用中遇到的的一些问题
制作ubuntu启动盘后,U盘只读. ubuntu自带的"启动盘创建器(usb-creator-gtk)"制作启动盘后,U盘只读. 打开ubuntu自带的"磁盘(hard ...
- C#读取邮件附件的方法
基于需求需要从邮件里读取附件,从网络搜索整理如下: 1 使用 Spire.Email 从官网下载安装并引用,地址:https://www.e-iceblue.com/Download/email-fo ...
- 【教程】基于Ubuntu系统的PyTorch虚拟环境配置
目录 一.PyTorch虚拟环境配置 二.PyTorch虚拟环境使用 三.常用命令 Editor: Veagau Time: 2019/10/17 一.PyTorch虚拟环境配置 该部分操作均在终端( ...
- HTTP协议详解(一)——初识HTTP及请求
何为HTTP(超文本传输协议)? 协议,即约定俗成的规范.HTTP则是浏览器与服务器之间交流的一种规范.HTTP基于TCP/IP协议,属于应用层的协议. 为什么Web应用不使用TCP或者UDP协议呢? ...
- Catalan数的理解
Catalan数的理解 f(0)=1 f(1)=1 f(2)=2 f(3)=5 f(4)=14 f(5)=42 f(2)=f(1)+f(1) f(3)=f(2)+f(1)*f(1)*f(2 ...
- centos 7 防火墙firewall 与iptables 的一些常用命令
CentOS 7的防火墙配置跟以前版本有很大区别,CentOS7这个版本的防火墙默认使用的是firewall,与之前的版本使用iptables不一样. firewall常用命令 service fir ...
- 爬虫基本库的使用---requests库
使用requests---实现Cookies.登录验证.代理设置等操作 处理网页验证和Cookies时,需要写Opener和Handler来处理,为了更方便地实现这些操作,就有了更强大的库reques ...
- Python3 下的输出字符控制
最近在使用 python3 进行爬虫的时候,出现了令人窒息的,只会在 python2 中遇到的,没想到在 python3 还能碰见的输出编码问题,报错如下: UnicodeEncodeError: ' ...
- NOIP模拟 11
差点迟到没赶上开题 开题后看了T1,好像一道原题,没分析复杂度直接敲了个NC线段树,敲了个暴力,敲了个对拍,就1h了.. 对拍还对出错了,发现标记下传有点问题,改了以后对拍通过,就把T1扔掉看T2 觉 ...