前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >springboot Jpa多数据源(不同库)配置

springboot Jpa多数据源(不同库)配置

作者头像
全栈程序员站长
发布于 2022-11-01 07:56:55
发布于 2022-11-01 07:56:55
2.5K00
代码可运行
举报
运行总次数:0
代码可运行

一、前言

springboot版本不同对多数据源配置代码有一定影响,部分方法和配置略有不同。 本文采用的springboot版本为2.3.12,数据源为mysql和postgresql


二、配置实战

2.1 基础pom

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${ 
mysql.version}</version>
</dependency>
</dependencies>

2.2 配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.datasource.mysql.jdbc-url=jdbc:mysql://localhost:3306/heilongjiang?characterEncoding=UTF-8&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8
spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.mysql.username=root
spring.datasource.mysql.password=123456
spring.datasource.pg.jdbc-url=jdbc:postgresql://localhost:5432/hljsyjt?useUnicode=true&characterEncoding=utf8&currentSchema=emergencydev,expert,public
spring.datasource.pg.driver-class-name=org.postgresql.Driver
spring.datasource.pg.username=postgres
spring.datasource.pg.password=postgres
spring.jpa.properties.hibernate.mysql-dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.pg-dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false

2.3 数据源配置类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.gsafety.bg.industrial.config;
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;
/** * @author Mr.wanter * @time 2021-8-11 0011 * @description */
@Configuration
public class DataSourceConfig { 

@Bean("dataSourceMysql")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.mysql")
public DataSource dataSourceMysql() { 

return DataSourceBuilder.create().build();
}
@Bean("dataSourcePg")
@ConfigurationProperties(prefix = "spring.datasource.pg")
public DataSource dataSourcePg() { 

return DataSourceBuilder.create().build();
}
}

2.4 数据源指定配置类

mysql指定数据源:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.gsafety.bg.industrial.config;
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.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.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;
/** * @author Mr.wanter * @time 2021-8-11 0011 * @description */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryMysql",//配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerMysql", //配置 事物管理器 transactionManager
basePackages = { 
"com.gsafety.bg.industrial.dao"}//设置持久层所在位置
)
public class MysqlDataSourceConfig { 

@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
// 自动注入配置好的数据源
@Autowired
@Qualifier("dataSourceMysql")
private DataSource mysqlDataSource;
// 获取对应的数据库方言
@Value("${spring.jpa.properties.hibernate.mysql-dialect}")
private String mysqlDialect;
/** * @param builder * @return */
@Bean(name = "entityManagerFactoryMysql")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactoryMysql(EntityManagerFactoryBuilder builder) { 

Map<String, String> map = new HashMap<>();
// 设置对应的数据库方言
map.put("hibernate.dialect", mysqlDialect);
jpaProperties.setProperties(map);
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
jpaProperties.getProperties(), new HibernateSettings());
return builder
//设置数据源
.dataSource(mysqlDataSource)
//设置数据源属性
.properties(properties)
//设置实体类所在位置.扫描所有带有 @Entity 注解的类
.packages("com.gsafety.bg.industrial.dao.po")
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("mysqlPersistenceUnit")
.build();
}
/** * 配置事物管理器 * * @param builder * @return */
@Bean(name = "transactionManagerMysql")
@Primary
PlatformTransactionManager transactionManagerMysql(EntityManagerFactoryBuilder builder) { 

return new JpaTransactionManager(entityManagerFactoryMysql(builder).getObject());
}
}

pg指定数据源:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.gsafety.bg.industrial.config;
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.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.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/** * @author Mr.wanter * @time 2021-8-11 0011 * @description */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPg",//配置连接工厂 entityManagerFactory
transactionManagerRef = "transactionManagerPg", //配置 事物管理器 transactionManager
basePackages = { 
"com.gsafety.bg.data.dao"}//设置持久层所在位置
)
public class PgDataSourceConfig { 

@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
//自动注入配置好的数据源
@Autowired
@Qualifier("dataSourcePg")
private DataSource PgDataSource;
// 获取对应的数据库方言
@Value("${spring.jpa.properties.hibernate.pg-dialect}")
private String pgDialect;
/** * @param builder * @return */
@Bean(name = "entityManagerFactoryPg")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPg(EntityManagerFactoryBuilder builder) { 

Map<String, String> map = new HashMap<>();
// 设置对应的数据库方言
map.put("hibernate.dialect", pgDialect);
jpaProperties.setProperties(map);
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
jpaProperties.getProperties(), new HibernateSettings());
return builder
//设置数据源
.dataSource(PgDataSource)
//设置数据源属性
.properties(properties)
//设置实体类所在位置.扫描所有带有 @Entity 注解的类
.packages("com.gsafety.bg.data.dao.po")
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("pgPersistenceUnit")
.build();
}
/** * 配置事物管理器 * * @param builder * @return */
@Bean(name = "transactionManagerPg")
PlatformTransactionManager transactionManagerPg(EntityManagerFactoryBuilder builder) { 

return new JpaTransactionManager(entityManagerFactoryPg(builder).getObject());
}
}

2.5 如何应用

数据源配置类中指定了扫描po和dao包的路径 例如entityManagerFactoryPg中的com.gsafety.bg.data.dao.po和com.gsafety.bg.data.dao 那么我们只需要在指定的包下创建po和dao即可,service包层次不受影响,自定义即可。 三数据源同理即可。 左侧为双数据源(与本篇实战内容一致),右侧为三数据源(三数据源目录结构示例)。

其他编码常规开发即可 po:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Entity
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "jc_repertory")
public class JcRepertoryPO implements Serializable { 

//some fields
}

dao:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface JcRepertoryDao extends JpaRepository<JcRepertoryPO, String>, JpaSpecificationExecutor<JcRepertoryPO> { 

}

service:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface JcRepertoryService { 

List<JcRepertoryPO> list();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Service
public class JcRepertoryServiceImpl implements JcRepertoryService { 

@Resource
private JcRepertoryDao jcRepertoryDao;
@Override
public List<JcRepertoryPO> list() { 

List<JcRepertoryPO> all = jcRepertoryDao.findAll();
return all;
}
}

controller 略 启动类添加扫描@SpringBootApplication_(_scanBasePackages = _{_"com.gsafety.bg.data", "com.gsafety.bg.industrial"_})_


三、遇到的问题

  1. 数据库连接报错 jdbcUrl is required with driverClassName

主要原因是在1.0 配置数据源的过程中主要是写成:spring.datasource.url 和spring.datasource.driverClassName。 而在2.0升级之后需要变更成:spring.datasource.jdbc-url和spring.datasource.driver-class-name

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring.datasource.pg.jdbc-url=jdbc:postgresql://localhost:5432/hljsyjt?useUnicode=true&characterEncoding=utf8&currentSchema=emergencydev,expert,public
spring.datasource.pg.driver-class-name=org.postgresql.Driver
  1. Paging query needs to have a Pageable parameter!

原系统中对jap的Repository进行了封装,采用常规方式调用即可。

  1. more than one ‘primary’ bean found among candidates

2.4 数据源指定配置类 中只有一个类中的方法添加 @Primary 另外一个不要加这个注解

  1. 互联网查询的代码中JpaProperties没有getHibernateProperties

与springboot版本有关,上面代码已修改。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179867.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月20日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[WPF] 如何实现文字描边
WPF 的 TextBlock 提供了大部分常用的文字修饰方法,在日常使用中基本够用。如果需要更丰富的表现方式,WPF 也提供了其它用起来复杂一些的工具去实现这些需求。例如这篇文章介绍的文字描边,就有几种方法可以在 WPF 中呈现。这篇文章将简单介绍这实现文字描边的方法。
dino.c
2022/05/07
1.2K0
[WPF] 如何实现文字描边
【NEW】WPF MVVM 模式下自写自用的窗口样式
SVG是一种图形文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形。它是基于XML(Extensible Markup Language),由World Wide Web Consortium(W3C)联盟进行开发的。严格来说应该是一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形页面。用户可以直接用代码来描绘图像,可以用任何文字处理工具打开SVG图像,通过改变部分代码来使图像具有交互功能,并可以随时插入到HTML中通过浏览器来观看。
Shunnet
2022/09/01
2.4K0
【NEW】WPF MVVM 模式下自写自用的窗口样式
WPF 如何画出1像素的线
如何有人告诉你,请你画出1像素的线,是不是觉得很简单,实际上在 WPF 上还是比较难的。 本文告诉大家,如何让画出的线不模糊
林德熙
2018/09/19
1.2K0
WPF 如何画出1像素的线
【愚公系列】2022年10月 基于WPF的智能制造MES系统框架-菜单栏的设计
MES系统为企业提供包括制造数据管理、计划排程管理、生产调度管理、库存管理、质量管理、人力资源管理、工作中心/设备管理、工具工装管理、采购管理、成本管理、项目看板管理、生产过程控制、底层数据集成分析、上层数据集成分解等管理模块,为企业打造一个扎实、可靠、全面、可行的制造协同管理平台。
愚公搬代码
2022/10/28
5690
wpf绘图性能分析
添加10000个图形节点大约1-2s,10w个图形需要5-6s,还是很慢,绘制的时候会调用gpu,但效率没提升多少,使用drawvisual还有一个问题是内存很高。
sofu456
2022/10/31
1K0
wpf绘图性能分析
WPF实现新手提示功能
本篇文章分享一个新手界面提示的案例,我们经常会在各种app中会遇到不断让你点下一步引导你使用客户端的提示,根据不同的参数配置显示不同提示气泡的样式。这里就分享一下在WPF中如何去实现,我们先看下面的效果。
JusterZhu
2022/12/07
5840
WPF实现新手提示功能
WPF 源代码 从零开始写一个 UI 框架
需要知道 WPF 是一个 UI 框架,作为一个 UI 框架,最主要的就是交互。也就是 UI 框架需要有渲染显示和处理用户输入的功能。 如果直接告诉大家 WPF 里面有哪些类,估计没有几位小伙伴会听下去,要么就是讲的类太简单,看过去我也就知道了,要么就是这个类可能我一直都不会用到他,即使可能会用到也早就忘了。 本文不会直接告诉大家 WPF 的源代码是如何写的,而是从零开始一起来写一个 UI 框架,在写的过程就会了解到为什么 WPF 可以这样写,为什么需要这样写,和 WPF 这样写的好处。 本文适合 WPF 的开发者同样也适合其他语言希望自己写一个 UI 框架的小伙伴。
林德熙
2019/03/13
3.7K2
WPF 源代码 从零开始写一个 UI 框架
[WPF]使用WindowChrome自定义Window Style
做了WPF开发多年,一直未曾自己实现一个自定义Window Style,无论是《WPF编程宝典》或是各种博客都建议使用WindowStyle="None" 和 AllowsTransparency="True",于是想当然以为这样就可以了。最近来了兴致想自己实现一个,才知道WindowStyle="None" 的方式根本不好用,原因有几点:
dino.c
2019/01/18
2.3K0
[WPF]使用WindowChrome自定义Window Style
WPF路由事件:路由事件的三种策略
路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件。路由事件是一个CLR事件。
zls365
2020/12/15
1.4K0
WPF/Silverlight Layout 系统概述——Measure
前言 在WPF/Silverlight当中,如果已经存在的Element无法满足你特殊的需求,你可能想自定义Element,那么就有可能会面临重写MeasureOverride和ArrangeOverride两个方法,而这两个方法是WPF/SL的Layout系统提供给用户的自定义接口,因此,理解Layout系统的工作机制,对自定义Element是非常有必要的。那么,究竟WPF/SL的Layout系统是怎么工作的呢?接下来,我简单的描述一下,然后,在后面的章节具体分析。 简单来说,WPF的Layout系统是一
葡萄城控件
2018/01/10
8580
WPF/Silverlight Layout 系统概述——Measure
WPF坐标转换
前言 假如屏幕是1920*1080,缩放是125%; 那么WPF窗口最大设置为1536*864就会占满屏幕。 获取鼠标位置 获取的是屏幕实际像素对应的位置。 using System.Runtime.InteropServices; namespace ColorPicker.Utils { internal class ZPoint { [DllImport("user32.dll", CharSet = CharSet.Auto)] public sta
码客说
2022/10/05
5190
WPF MVVM 模式下自写自用的窗口样式
废话我也就不多说,直接上菜(由于公司电脑做了加密,无法把代码压缩发布,只能以这种方式来分享)
Shunnet
2022/09/01
1.7K0
WPF MVVM 模式下自写自用的窗口样式
浅谈window桌面GUI技术及图像渲染性能测试实践
从Windows Vista之后,desktop composition的部分就由Desktop Window Manager完成了(当然是启用Aero的情况下,Windows 8起DWM是必须开启的)
高楼Zee
2019/07/17
4K0
浅谈window桌面GUI技术及图像渲染性能测试实践
WPF 跨线程 UI 的方法
本文告诉大家如何在 WPF 使用多线程的 UI 的方法 在很多的时候都是使用单线程的 UI 但是有时候需要做到一个线程完全处理一个耗时的界面就需要将这个线程作为另一个 UI 线程
林德熙
2019/03/13
1.8K0
WPF 跨线程 UI 的方法
【愚公系列】2023年04月 WPF运动控制平台-005.运动平台之功能实现(完结)
---- 一、运动平台之功能实现 1.位置计算 物理可用距离 (40000), 取料位:19945P, 打包位:-19360P 像素位置:取料位:20px 打包位:1020px 把脉冲转换位距离 步进驱动器设置细分 8 步进电机步进角 1.8° 导程:8mm 计算步进电机走1cm需要的脉冲数 360 / 1.8 = 200个脉冲转一圈 200 * 8 = 1600个脉冲转一圈(细分情况) 1600 / 8 = 200 (步进电机走1mm需要) 故:走1cm需要脉冲
愚公搬代码
2023/04/28
4580
【愚公系列】2023年04月 WPF运动控制平台-005.运动平台之功能实现(完结)
WPF/Silverlight Layout 系统概述——Arrange
上一篇我们介绍了WPF/Silverlight Layout系统的Measure过程,本文将继续介绍Arrange过程。 Arrange过程概述 普通基类属性对Arrange过程的影响 我们知道Measure过程是在确定DesiredSize的大小,以便Arrange过程参考这个DesiredSize,确定给MyPanel分配多少空间,但是DesiredSize只是作为参考,在有些用例下,MyPanelParent在调用MyPanel.Arrange的时候,会根据父的实际策略指定MyPanel.Arrang
葡萄城控件
2018/01/10
8200
WPF/Silverlight Layout 系统概述——Arrange
WPF快速入门系列(1)——WPF布局概览
  关于WPF早在一年前就已经看过《深入浅出WPF》这本书,当时看完之后由于没有做笔记,以至于我现在又重新捡起来并记录下学习的过程,本系列将是一个WPF快速入门系列,主要介绍WPF中主要的几个不同的特性,如依赖属性、命令、路由事件等。
zls365
2020/11/10
3.1K0
WPF快速入门系列(1)——WPF布局概览
少量代码设计一个登录界面 - .NET CORE(C#) WPF开发
继续 MaterialDesignThemes 开源控件库学习,本文简单使用输入控件的水印附加属性:materialDesign:HintAssist.Hint。
zls365
2020/12/29
1.6K0
少量代码设计一个登录界面 - .NET CORE(C#) WPF开发
[UWP]用Shape做动画
相对于WPF/Silverlight,UWP的动画系统可以说有大幅提高,不过本文无意深入讨论这些动画API,本文将介绍使用Shape做一些进度、等待方面的动画,除此之外也会介绍一些相关技巧。
dino.c
2019/01/18
2.1K0
[UWP]用Shape做动画
[WPF自定义控件]从ContentControl开始入门自定义控件
我去年写过一个在UWP自定义控件的系列博客,大部分的经验都可以用在WPF中(只有一点小区别)。这篇文章的目的是快速入门自定义控件的开发,所以尽量精简了篇幅,更深入的概念在以后介绍各控件的文章中实际运用到才介绍。
dino.c
2019/05/17
4.1K0
推荐阅读
相关推荐
[WPF] 如何实现文字描边
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验