SpringBoot多数据源(一)

SpringBoot多数据源(一)

  • 1.多数据源使用场景
    • 1.1 业务复杂(数据量大)
    • 1.2 读写分离
  • 2.多数据源配置
  • 3.应用
  • 4.测试

1.多数据源使用场景

1.1 业务复杂(数据量大)

简单理解就是业务量复杂,将庞大的数据拆到多个数据库中。或者由于公司有多个子项目,各用各的数据库,涉及数据共享

1.2 读写分离

为了解决数据库的读性能瓶颈(读比写性能更高,写锁会影响读阻塞,从而影响读的性能)

与上述1.1不同的是,在读写分离中,主库和从库的数据库是一致的(不考虑主从延迟)。数据更新操作(insertupdatedelete)都是在主库上进行的,主库将数据更新信息同步给
从库。在查询时,可以在从库上进行。从而分担主库的压力。

2.多数据源配置

spring:
  datasource:
    #数据源1
    datasource1:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/test_master
      username: root
      password: root
      druid:
         initial-size: 1
         min-idle: 1
         max-active: 20
         test-on-borrow: true

    #数据源2
    datasource2:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbc-url: jdbc:mysql://localhost:3306/test_slave
      username: root
      password: root
      druid:
        initial-size: 1
        min-idle: 1
        max-active: 20
        test-on-borrow: true

# mybatis的配置
mybatis:
  type-aliases-package: com.rql.entity
  mapper-locations: classpath:mybatis/*.xml

这里在配置时,特别注意在使用多配置源时,要将url改为jdbc-url

对应两个数据库:

在这里插入图片描述

3.应用

下面是一个简单的SpringBoot整合mybatis的项目目录层级:

在这里插入图片描述

其中DataSourceConfig用于定义DataSource Bean,并通过@ConfigurationProperties注解将配置文件中的属性映射到该Bean的属性上
DataSourceConfig.java

@Configuration
public class DataSourceConfig {

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

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

上面只是创建了两个DataSourceBean,分别为dataSource1dataSource2,如果想要动态地根据操作去调用不同的数据源,那么就需要再创建一个Bean,类似于代理的角色,根据条件来选择不同的数据源。

因此,创建DynamicDataSource.java,并实现了DataSource接口。



@Component
@Primary
public class DynamicDataSource implements DataSource, InitializingBean {

    public static ThreadLocal<String> name=new ThreadLocal<>();

    @Autowired
    DataSource dataSource1;

    @Autowired
    DataSource dataSource2;

    @Override
    public Connection getConnection() throws SQLException {
        if (name.get().equals("w")) {
            return dataSource1.getConnection();
        }
        else {
            return dataSource2.getConnection();
        }
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public void afterPropertiesSet() throws Exception {

        name.set("w");
    }
}

这里主要通过getConnection()方法来选择需要连接的数据源,因此根据读写操作的不同,设置一个值来区别(一般是使用枚举值,这样后面修改时不至于到代码中挨个去找),文中主要设置了一个参数,为了讲述方面。

public static ThreadLocal<String> name=new ThreadLocal<>();

注意到DynamicDataSource.java也实现了InitializingBean 接口。

InitializingBean接口是Spring Framework中的一个重要接口,其主要目的是在Bean实例化后进行初始化操作。具体来说,当一个Bean实现了InitializingBean接口并被Spring容器创建后,Spring会在该Bean的属性设置完成后自动调用afterPropertiesSet()方法来执行一些额外的初始化逻辑。

因此,这里在Bean实例化后,设置了name的初始值。

4.测试

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserDao userDao;

    @GetMapping("/a")
    public List<User> selectUsers(){
        DynamicDataSource.name.set("r");
        return userDao.findAll();
    }

    @PostMapping("/b")
    public void insertUser(@RequestBody User user){
        DynamicDataSource.name.set("w");
        userDao.inserUser(user);
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UML/SysML建模工具更新情况-截至2024年4月(1)5款-Trufun建模平台 v2024

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 工具最新版本&#xff1a;itemis CREATE 5.2.2 更新时间 2024年3月22日 工具简介 原名YAKINDU Statechart Tools。状态机建模工具&#xff0c;支持各种语言的代码生成&#xff0c;提…

1000kW 柴油发电机组测试负载箱的核心功能

随着科技的不断发展&#xff0c;电力系统的稳定性和安全性日益受到重视。柴油发电机组作为一种重要的备用电源设备&#xff0c;其性能和可靠性直接关系到电力系统的稳定运行。为了确保柴油发电机组的性能和可靠性&#xff0c;对其进行定期的检测和维护是必不可少的。 在这个过程…

电磁仿真--基本操作-CST-(1)

目录 1. 开启-备忘 2. 从调用最简单的Dipole天线开始 2.1 查找示例 2.2 运行示例 2.3 进度与消息 2.4 查看结果 2.4.1 Port signals 2.4.2 S-Parameter 2.4.3 Reference Impedance 2.4.4 Balance 2.4.5 Power 2.4.6 Energy 2.4.7 Discrete Ports 2.4.8 2D/3D Res…

Spring Boot后端+Vue前端:打造高效二手车交易系统

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

Linux服务器硬件及RAID配置

一、服务器硬件 塔式服务器&#xff1a;最初的服务器形态之一&#xff0c;类似于传统的台式电脑&#xff0c;但具有更强的处理能力和稳定性&#xff0c;适合小型企业或部门使用。 机架式服务器&#xff1a;设计为可安装在标准化机架内的模块化单元&#xff0c;可以有效地节省空…

好用的AI绘画工具,5个一键AI自动生成绘画推荐

在数字时代&#xff0c;AI绘画软件开启了人们展现创意的全新篇章。如果你对AI一键生成绘画的感兴趣&#xff0c;那就跟着我一起来了解一下吧&#xff01; 1.爱制作AI 爱制作AI是一款功能强大的人工智能软件&#xff0c;它不仅拥有超强的AI问答能力&#xff0c;还能轻松搞定绘画…

Aigtek功率放大器的使用方法有哪些

功率放大器是一种将小信号放大为大信号的电子设备&#xff0c;广泛应用于无线通信、音频系统、雷达等领域。在使用功率放大器时&#xff0c;需要注意以下几个方面&#xff1a; 电源供应&#xff1a;功率放大器需要提供稳定的电源供应以保证正常工作。通常情况下&#xff0c;功率…

2021年全国大学生电子设计竞赛D题——基于互联网的摄像测量系统(三)

13 测试方案和测量结果 测量一个边长为1米的正方形&#xff0c;取三个顶点分别作为O、A、B点。 在O点上方&#xff0c;用细线悬挂激光笔&#xff0c;激光笔常亮向下指示&#xff0c;静止时激光笔的光点和O点重合。 将两个D8M摄像头子卡插到DE10-Nano开发板上&#xff0c;放…

按摩上门小程序源码系统 带完整的安装代码包以及搭建教程

随着人们生活节奏的加快&#xff0c;越来越多的人开始追求便捷、高效的生活方式。按摩服务作为一种放松身心、缓解压力的方式&#xff0c;受到了广大消费者的青睐。然而&#xff0c;传统的按摩服务往往受到时间、地点等因素的限制&#xff0c;难以满足消费者的即时需求。因此&a…

ansible进阶-剧本调试方法

目录 1、调试方法 2、实例 2.1 Debug模块 2.2 tags标签 2.3 忽略错误 1、调试方法 具体方法应用场景debug标签执⾏剧本的时候输出剧本的执⾏流程,⼀般配合register⼀起使⽤. 输出facts变量自定义变量tags标签给⼀些模块加上标签,运⾏剧本的时候可以运⾏指定标签的…

Halo自定义文章分类

在自定义站点的时候&#xff0c;往往需要再特定的页面展示个性的内容&#xff0c;为了满足这个特殊的要求&#xff0c;就需要文章自定义标签&#xff0c;然后挂载到自定义下面达到自己要的效果。 Halo版本 版本&#xff1a;2.12在theme.yaml指定文章分类页 spec:customTempla…

springboot 载入自定义的yml文件转DTO

改进方法&#xff0c;直接spring注入 import cn.hutool.json.JSONUtil; import org.springframework.beans.factory.config.YamlMapFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import …

Pulsar【部署 01】消息队列PULSAR在Linux环境的主程序安装使用(小内存服务器问题处理)

官方网站&#xff1a;https://pulsar.apache.org/ 对于本地开发和测试&#xff0c;您可以在机器上以单机模式运行Pulsar。单机模式在单个Java虚拟机(JVM)进程中运行所有组件。本地单机版安装手册&#xff1a; 消息队列PULSAR在Linux环境的主程序安装使用 1.Prerequisites1.1 Pu…

万兆以太网MAC设计(4)CRC_process模块

文章目录 前言一、模块功能二、实现过程三、仿真总结 前言 上文介绍的MAC_RX模块当中增加了CRC校验和比对的功能&#xff0c;本文将根据CRC校验的结果&#xff0c;来决定将数据输出到上层用户还是丢弃。 一、模块功能 接收MAC_RX模块输出的AXIS数据&#xff0c;存入本地环形…

每日两题1

文章目录 使用最小花费爬楼梯91解码方法 使用最小花费爬楼梯 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {if(cost.size() 2)return min(cost[0],cost[1]);vector<int> dp;dp.reserve(cost.size()1);dp[0] 0;dp[1] 0;for(int i…

Flink KafkaSink分区配置的不同版本对比

Flink KafkaSink分区配置的不同版本对比 在不同版本的Flink中&#xff0c;KafkaSink 分区默认配置方式可能会有一些变化。以下是摘自Flink官方文档不同版本的原文&#xff1a; 1. Flink版本&#xff1a;1.12~1.19 Sink 分区 # 配置项 sink.partitioner 指定了从 Flink 分区到 …

eBay、亚马逊自养号测评如何避免风控账号关联选择合适网络IP环境

在自养号下单中选择适合的网络环境至关重要。经过多次实践与测试&#xff0c;积累了大量的经验&#xff0c;希望能够与大家分享&#xff0c;帮助大家避开陷阱&#xff0c;顺利前行。 市面上的网络环境种类繁多&#xff0c;从纯IP类的Luminati、Rola&#xff0c;到纯环境类的VM…

Redis 的数据结构和内部编码

Redis的 5 种数据类型 Redis 底层在实现上述数据结构的时候&#xff0c;会在源码层面&#xff0c;针对上述实现进行 特定的优化 &#xff0c;来达到节省时间/节省空间效果 特定的优化&#xff1a;内部的具体实现的数据结构&#xff0c;在特定场景下&#xff0c;不是其对应的标准…

ros1 C++ 输出helloworld

1、创建工作空间并初始化 mkdir -p 自定义空间名称/src cd 自定义空间名称 catkin_make运行完&#xff0c;生成文件如下图&#xff1a; 2、进入 src 创建 ros 包并添加依赖 cd src catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs这里&#xff0c;我的自定义ROS包名…

VUE 页码分页封装

VUE 页码封装组件 pagination/index.vue &#xff1a; <template><div class"pagination-contianer"><el-pagination background layout"prev, pager, next" :total"total" current-change"currentChange"> </e…