Spring Boot中JdbcTemplate多数据源配置

作者简介:大家好,我是撸代码的羊驼,前阿里巴巴架构师,现某互联网公司CTO

联系v:sulny_ann(17362204968),加我进群,大家一起学习,一起进步,一起对抗互联网寒冬


在《Spring Boot中JdbcTemplate源码分析》中讲到了自动配置相关的源代码实现。基于Spring Boot自动配置默认配置的组件,我们可以来自定义JdbcTemplate的实例化。而多数据源的配置就是在此基础上实例化多个数据源和JdbcTemplate。

下面,我们来看具体的源代码实现。

依赖类库

关于依赖类库与集成JdbcTemplate时的一样,Spring Boot版本2.2.2.RELEASE。

相关pom依赖如下:

<dependencies>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>
    <!--数据库连接相关-->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-jdbc</artifactId>    </dependency>    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>    </dependency>
    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>        <optional>true</optional>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>        <exclusions>            <exclusion>                <groupId>org.junit.vintage</groupId>                <artifactId>junit-vintage-engine</artifactId>            </exclusion>        </exclusions>    </dependency></dependencies>

spring-boot-starter-jdbc是集成jdbc的依赖,mysql-connector-java是基于mysql的依赖类库。lombok是简化代码的工具类,如果不需要可去掉,并去掉类中相关的注解。

spring-boot-starter-test为单元测试依赖的类库,这里单元测试使用的是junit5,注意使用方法与junit4差别比较大。

配置application

application.properties配置如下:​​​​​​​

spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=truespring.datasource.primary.username=rootspring.datasource.primary.password=root_123spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/spring1?serverTimezone=UTC&useUnicode=true\  &characterEncoding=utf-8&useSSL=truespring.datasource.secondary.username=rootspring.datasource.secondary.password=root_123spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

既然是多数据源,肯定要配置多个数据源的配置。与单数据源配置基本形式差不多。

需要注意的是第一个配置项的key为:spring.datasource.primary.jdbc-url。与单数据源时使用的spring.datasource.url有所区别。不然,启动时会抛出异常。

多数据源对应的Java配置

下面就需要我们自己来实例化DataSource和JdbcTemplate。相关的实例化也可参看源码解析文章中Spring Boot的实例化方式。

这里,我们的实现如下:​​​​​​​

@Configurationpublic class DataSourceConfig {
  @Primary  @Bean(name = "primaryDataSource")  @ConfigurationProperties(prefix="spring.datasource.primary")  public DataSource primaryDataSource() {    return DataSourceBuilder.create().build();  }
  @Bean(name = "secondaryDataSource")  @ConfigurationProperties(prefix="spring.datasource.secondary")  public DataSource secondaryDataSource() {    return DataSourceBuilder.create().build();  }
  @Bean(name="primaryJdbcTemplate")  public JdbcTemplate primaryJdbcTemplate (@Qualifier("primaryDataSource")  DataSource dataSource ) {    return new JdbcTemplate(dataSource);  }
  @Bean(name="secondaryJdbcTemplate")  public JdbcTemplate  secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {    return new JdbcTemplate(dataSource);  }
}

@Configuration声明该类为配置类。

@Primary指定当出现多个相同类型的实例化对象时,以该注解标注的为默认的。

@Bean实例化Bean,并将其注入到容器当中。这里分别实例化了primaryDataSource和secondaryDataSource两个DataSource,以Bean的名称来区分。

@ConfigurationProperties将前缀为spring.datasource.primary和前缀为spring.datasource.secondary的配置属性设置到对应的DataSource中。

随后实例化了两个JdbcTemplate,直接通过new关键字创建,并且把对应的DataSource作为构造参数传入。

经过该配置文件的配置,便有了两个JdbcTemplate。

实体类

实体类如下:​​​​​​​

@Datapublic class Order {
  private int id;
  private String orderNo;
  private int amount;}

@Data为Lombok的注解,自动生成一些默认的方法,比如属性的getter/setter方法。

数据库

关于数据库的DDL如下:​​​​​​​

CREATE TABLE `tb_order` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `amount` int(11) NOT NULL DEFAULT '1',  `order_no` varchar(64) NOT NULL DEFAULT '',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

同样的表在两个数据库中进行创建。

接口定义

定义OrderService接口:​​​​​​​

public interface OrderService {
  /**   * 创建订单   * @param order 订单信息   * @return 记录数   */  int save(Order order);
  /**   * 保存到指定库   * @param order 订单信息   * @param jdbcTemplate jdbc   * @return   */  int save(Order order, JdbcTemplate jdbcTemplate);}

接口实现:​​​​​​​

@Service("orderService")public class OrderServiceImpl implements OrderService {
  @Resource  @Qualifier("primaryJdbcTemplate")  private JdbcTemplate jdbcTemplate;
  @Override  public int save(Order order) {    return jdbcTemplate.update("insert into tb_order(order_no, amount) values(?, ?)", order.getOrderNo(),        order.getAmount());  }
  @Override  public int save(Order order, JdbcTemplate secJdbcTemplate) {    if (secJdbcTemplate != null) {      return secJdbcTemplate.update("insert into tb_order(order_no, amount) values(?, ?)", order.getOrderNo(),          order.getAmount());    } else {      return jdbcTemplate.update("insert into tb_order(order_no, amount) values(?, ?)", order.getOrderNo(),          order.getAmount());    }  }}

在实现方法中,默认注入了主库的JdbcTemplate,同时在原来的save方法中新增了一个JdbcTemplate参数,可以根据是否传递该新的JdbcTemplate来决定使用哪个JdbcTemplate。

当然在此方法内也可以使用一个JdbcTemplate,然后根据参数动态的修改该JdbcTemplate指向的具体实现类。可以根据具体情况进行灵活运用。

单元测试

单元测试类如下:

@Slf4j@SpringBootTestclass OrderServiceTest {
  @Resource  private OrderService orderService;
  @Resource  @Qualifier("primaryJdbcTemplate")  private JdbcTemplate primaryJdbcTemplate;
  @Resource  @Qualifier("secondaryJdbcTemplate")  private JdbcTemplate secondaryJdbcTemplate;
  @Test  void save() {    Order order = new Order();    order.setOrderNo("N003");    order.setAmount(10000);    orderService.save(order, primaryJdbcTemplate);    orderService.save(order, secondaryJdbcTemplate);  }}

执行以上单元测试,两个库中的tb_order表分别插入了一条数据。关于其他增删改查操作,可参考保存方法进行扩展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编译 Flink代码

构建环境 JDK1.8以上和Maven 3.3.x可以构建Flink&#xff0c;但是不能正确地遮盖某些依赖项。Maven 3.2.5会正确创建库。所以这里使用为了减少问题选择 Maven3.2.5版本进行构建。要构建单元测试&#xff0c;请使用Java 8以上&#xff0c;以防止使用PowerMock运行器的单元测试失…

云计算核心技术

1.1 云计算的定义 云计算是目前业内的热点概念&#xff0c;它以开放的标准和服务为基础&#xff0c;以互联网为中心&#xff0c;提供安全、快速、便捷的数据存储和网络计算服务&#xff0c;让互联网这片“云”上的各种计算机共同组成数个庞大的数据中心及计算中心。它可以被看成…

求职智能分析系统

本项目是一个基于Flask轻量级框架的计算机就业数据可视化分析平台。 采用echarts和ajax等技术进行数据展示和用户交互。

【电路笔记】-电位器

电位器 文章目录 电位器1、概述2、电位器类型2.1 旋转电位器2.2 滑块电位器2.3 预设和微调电位器2.4 变阻器 3、电位器示例14、电位器作为分压器5、电位器示例26、变阻器6、滑块变阻器7、线性或对数电位器8、总结 当连接的轴物理旋转时&#xff0c;电位计和变阻器的电阻值会发生…

一个简单的Wireshark和TCP三次握手,为什么能难住阿里6年测试?

之前写过一篇博客&#xff1a;用 Fiddler 来调试HTTP&#xff0c;HTTPS。 这篇文章介绍另一个好用的抓包工具wireshark&#xff0c; 用来获取网络数据封包&#xff0c;包括http,TCP,UDP&#xff0c;等网络协议包。 记得大学的时候就学习过TCP的三次握手协议&#xff0c;那时候…

Vue中 v-show 和 v-if 有什么区别

Vue中的 v-show 和 v-if 一.v-show 与 v-if 原理分析v-show 原理v-if 原理 二、v-show 与 v-if 的共同点三、v-show 与 v-if 的区别四、v-show 与 v-if 的使用场景使用 v-show 的场景&#xff1a;使用 v-if 的场景&#xff1a; 五、v-show 与 v-if 的优缺点v-show优点&#xff…

kafka rebalance(再均衡)导致的消息积压分析

起因&#xff1a; 某天&#xff0c;项目组收到大量的kafka消息积压告警。查看了kafka日志后&#xff0c;发现 kafka不断地 rebalance(再均衡)。 Rebalance (再均衡)&#xff1a; 分区的所有权从一个消费者转移到另一个消费者&#xff0c;这样的行为被称为Rebalance (再均衡)…

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶。 自动驾驶汽车依靠人工智能、视觉计算、雷达、监控装置和全球定位系统协同合作,让电脑可以在没有任何人类主动的操作下,自动安全地操作机动车辆。 演示视频: Openpilot :一个开源的汽车驾…

Socks5代理与代理IP的技术创新

随着全球市场的开放和跨界电商的崛起&#xff0c;企业在出海过程中面临着复杂多变的网络环境和地域限制。在这一背景下&#xff0c;Socks5代理和代理IP等技术应运而生&#xff0c;成为助力企业突破网络壁垒、实现出海目标的重要工具。本文将深入探讨Socks5代理和代理IP在跨界电…

OpenSSL 3.x爆出漏洞,如何妥善应对?

10月25日&#xff0c;OpenSSL项目团队发布了OpenSSL 3.x版中一个关键安全漏洞的修复程序。该修复程序已于11月1日正式发布。 由于OpenSSL有着极为广泛的使用&#xff0c;该公告引起了很大反响。Akamai希望能通过本文帮助相关用户了解情况&#xff0c;介绍有关检测和缓解威胁的…

怎么消除视频中所有的声音?方法很简单

当我们想把视频中去掉声音&#xff0c;可能有多种原因&#xff0c;也许需要制作一个无声视频&#xff0c;或者想在视频中添加自己的音乐或解说&#xff0c;特别是一些搞笑解说&#xff0c;无论原因是什么&#xff0c;到底要怎么把视频中所有的声音都去除呢&#xff1f; 小编给…

计算机毕业设计 基于Web的网上购物系统(pc端仿淘宝系统)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

SVN优缺点详解及版本控制系统选型建议

Subversion (SVN)是目前可用的众多版本控制选项之一。本篇文章将全面概述什么是 SVN、SVN的历史、SVN存储库是什么&#xff0c;以及在切换到SVN之前您应该谨慎考虑的潜在问题。 什么是Subversion&#xff08;SVN&#xff09;&#xff1f; Subversion软件&#xff0c;也称为SV…

管理类联考——数学——真题篇——按知识分类——代数

文章目录 2023真题(2023-09)-代数-一元二次方程-注意绝对值的有效性真题(2023-17)-代数-一元二次方程-举反例真题(2023-18)-数列-等比数列真题(2023-24)-数列-等比数列2022真题(2022-03)-代数-整式-因式分解真题(2022-19)-数列-等比数列真题(2022-21)-数列-等比数…

Docker的常用命令(没有废话)

目录 镜像 镜像管理命令 镜像构建命令 镜像标签和推送命令 其他命令 容器 运行容器 停止和删除容器 查看容器信息 进入容器 数据卷 列出卷 创建和删除卷 将卷挂载到容器 镜像 镜像管理命令 docker images # 列出本地所有的镜像 docker search <关键词> #…

使用pe安装windows操作系统

一、系统安装前准备工作&#xff0c;制作系统盘 &#xff08;1&#xff09;拷贝电脑上的资料 &#xff08;2&#xff09;准备一个至少8G的U盘 &#xff08;3&#xff09;下载windows镜像文件及pe软件 通过百度网盘可下载下列软件及镜像 windows镜像文件&#xff08;百度网盘…

知识笔记(五十二)———MySQL 安装

Linux/UNIX 上安装 MySQL Linux平台上推荐使用RPM包来安装Mysql,MySQL AB提供了以下RPM包的下载地址&#xff1a; MySQL - MySQL服务器。你需要该选项&#xff0c;除非你只想连接运行在另一台机器上的MySQL服务器。MySQL-client - MySQL 客户端程序&#xff0c;用于连接并操作…

Kotlin 中的 `as` 关键字:类型转换的艺术

在 Android 编程中&#xff0c;类型转换是一项常见的操作。为了使这一过程更加流畅和安全&#xff0c;Kotlin 提供了 as 关键字。本文将深入探讨 as 关键字的用法和最佳实践。 一、as 关键字的基本概念 &#x1f680; as 关键字在 Kotlin 中用于显式类型转换。它将一个表达式…

vue零基础

vue 与其他框架的对比 框架设计模式数据绑定灵活度文件模式复杂性学习曲线生态VueMVVM双向灵活单文件小缓完善ReactMVC单向较灵活all in js大陡丰富AngularMVC双向固定多文件较大较陡&#xff08;Typescript&#xff09;独立 更多对比细节&#xff1a;vue 官网&#xff1a;ht…

matplotlib绘图时show函数需在save函数后

matplotlib绘图时&#xff0c;先调用show&#xff0c;后调用save函数保存图像&#xff0c;否则无法保存图像信息 figsize 23,10 #fig, axes plt.subplots(nrows1, ncols2) fig, axs plt.subplots(4, 3, sharexcol,shareyrow,figsizefigsize) # 在每个子图中绘制一个图形 pi…