自定义多数据源

多数据源

第一章 自定义多数据源


文章目录

  • 多数据源
  • 前言
  • 一、先在配置文件中配置好多个数据源
  • 二、配置数据源的配置文件
  • 三、定义动态数据源配置
    • 1、自定义了Datasource,主要目的是为了在Spring容器中定义一个datasource的Bean,用于mybtais获取数据库连接使用。 2、为jdbc获取数据连接 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b84024bd2cf842e0b36bd4a29784c32a.png)
  • 四、自定义注解,用来判断curd,按照不同的操作类型进行区分
  • 总结


前言

本案例是使用spring-boot+mysql 来作为案例,需要先搭建好服务。


一、先在配置文件中配置好多个数据源

具体配置示例:

server:
  port: 8080
spring:
  datasource:
    datasource1:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://192.168.180.129:13306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
      hikari:
        minimum-idle: 5
        idle-timeout: 600000
        maximum-pool-size: 10
        auto-commit: true
        pool-name: MyHikariCP
        max-lifetime: 1800000
        connection-timeout: 30000
        connection-test-query: SELECT 1

    datasource2:
      type: com.zaxxer.hikari.HikariDataSource
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://192.168.180.129:13306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
      hikari:
        minimum-idle: 5
        idle-timeout: 600000
        maximum-pool-size: 10
        auto-commit: true
        pool-name: MyHikariCP
        max-lifetime: 1800000
        connection-timeout: 30000
        connection-test-query: SELECT 1


配置了两个数据源,datasource1和datasource2,分别用来表示写与读的数据源

二、配置数据源的配置文件

具体代码示例:

@Configuration
public class DataSourceConfig {

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

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

1、分别为spring容器定义了两个datasource,同时限定了不同的数据源读取不同的配置
2、具体的限定条件为spring.datasource.datasourcexxxx。

三、定义动态数据源配置

具体代码示例:

@Component
@Primary
public class DynamicDataSource implements DataSource {

    public static ThreadLocal<OperationTypeEnum> operationType = ThreadLocal.withInitial(() -> OperationTypeEnum.WRITE);

    @Autowired
    private DataSource dataSource1;

    @Autowired
    private DataSource dataSource2;

    @Override
    public Connection getConnection() throws SQLException {
        OperationTypeEnum operationTypeEnum = operationType.get();
        switch (operationTypeEnum) {
            case READ:
                return dataSource2.getConnection();
            case WRITE:
            case DELETE:
            case UPDATE:
                return dataSource1.getConnection();
        }
        return dataSource1.getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        OperationTypeEnum operationTypeEnum = operationType.get();
        switch (operationTypeEnum) {
            case READ:
                return dataSource2.getConnection(username, password);
            case WRITE:
            case DELETE:
            case UPDATE:
                return dataSource1.getConnection(username, password);
        }
        return dataSource1.getConnection(username, password);
    }

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

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

    @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;
    }
}

1、自定义了Datasource,主要目的是为了在Spring容器中定义一个datasource的Bean,用于mybtais获取数据库连接使用。
2、为jdbc获取数据连接
在这里插入图片描述

四、自定义注解,用来判断curd,按照不同的操作类型进行区分

1、注解的定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JdbcOperationAnnotation {
    OperationTypeEnum value() default OperationTypeEnum.WRITE;
}

2、操作类型枚举的定义

@Getter
public enum OperationTypeEnum {

    WRITE(0),
    READ(1),
    UPDATE(2),
    DELETE(3);

    private Integer code;

    OperationTypeEnum(Integer code) {
        this.code = code;
    }
}

3、切面的定义

@Slf4j
@Aspect
@Component
public class JdbcOperationAspect {

    @Around("@annotation(jdbcOperationAnnotation)")
    public Object aroundJdbcOperation(ProceedingJoinPoint joinPoint, JdbcOperationAnnotation jdbcOperationAnnotation) throws Throwable {
        log.info("读取注解信息: {}"+ JSON.toJSONString(jdbcOperationAnnotation));
        OperationTypeEnum operationTypeEnum = jdbcOperationAnnotation.value();
        switch (operationTypeEnum) {
            case READ:
                DynamicDataSource.operationType.set(OperationTypeEnum.READ);
                break;
            case WRITE:
                DynamicDataSource.operationType.set(OperationTypeEnum.WRITE);
                break;
            case UPDATE:
                DynamicDataSource.operationType.set(OperationTypeEnum.UPDATE);
                break;
            case DELETE:
                DynamicDataSource.operationType.set(OperationTypeEnum.DELETE);
        }
        return joinPoint.proceed();
    }
}

4、注解的使用

@Mapper
public interface UserMapper {

    @JdbcOperationAnnotation(OperationTypeEnum.READ)
    @Select("select * from user where username = #{username}")
    User selectUser(String username);

    @JdbcOperationAnnotation(OperationTypeEnum.WRITE)
    @Insert("insert into user(username, password) values (#{username}, #{password})")
    void addUser(@Param("username") String username, @Param("password") String password);
}

总结

通过重新实现 DataSource 接口,我们可以掌控数据库连接的创建和管理,确保程序按照我们期望的方式执行。这个自定义的过程让我们能够更好地适应特定的业务需求和性能要求,从而优化数据库操作的执行流程。这种灵活性和控制权是自定义数据源的核心优势,让我们能够更好地满足应用程序的需求,确保其稳定性和高效性。

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

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

相关文章

kali工具----网络映射器(Network Mapper)

识别活跃的主机 尝试渗透测试之前&#xff0c;必须先识别在这个目标网络内活跃的主机。在一个目标网络内&#xff0c;最简单的方法将是执行ping命令。当然&#xff0c;它可能被一个主机拒绝&#xff0c;也可能被接收。本节将介绍使用Nmap工具识别活跃的主机。 1、网络映射器工具…

【迅为iTOP-4412-linux 系统制作(4)】ADB 或者 TF 卡烧写测试

准备工作 编译生成的内核镜像uImage 和设备树 dtb 文件“exynos4412-itop-elite.dtb”已经可以使用了。 把编译生成的uimage和dtb文件。拷贝fastboot工具。官方的u-boot-iTOP-4412.bin 也拷贝到 platform-tools 文件夹目录内。system.img 也拷贝到 platform-tools 文件夹目录…

【Java EE】 IoC详解(Bean的存储)

文章目录 &#x1f38d;Controller&#xff08;控制器存储&#xff09;&#x1f338;如何从Spring容器中获取对象&#xff08;ApplicationContext&#xff09;&#x1f338;获取bean对象的其他方式&#xff08;BeanFactory&#xff09;&#x1f338;Bean 命名约定&#x1f338;…

[ROS 系列学习教程] 建模与仿真 - Gazebo 与 URDF 建模介绍

ROS 系列学习教程(总目录) 本文目录 一、Gazebo 介绍二、URDF 建模介绍2.1 一个简单的实体2.2 rivz显示URDF模型2.3 保存与加载rviz配置2.4 launch文件快速启动2.5 package结构 由于种种原因&#xff0c;有时我们不能直接使用真实的机器人进行调试&#xff0c;这时就需要对机器…

Tomcat源码解析——源码环境搭建

一、源码下载 在进行源码阅读前&#xff0c;先下载源码包&#xff0c;这样便于做笔记和debug。 我所用的版本是Tomcat7.0.68&#xff0c; Tomcat7.0.68下载地址&#xff1a;Index of /dist/tomcat/tomcat-7/v7.0.68/src 所有Tomcat的源码包下载地址&#xff1a;Index of /dist/…

【C++庖丁解牛】哈希表/散列表的设计原理 | 哈希函数

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.哈希概念2.哈希冲突…

每日一题(力扣)---从中序与后序遍历序列构造二叉树

思路 根据中序遍历和后序遍历的特性可知&#xff0c;后序遍历的最后一个元素为根元素。然后找到中序遍历中对应的序号。将中序遍历的划分为两部分&#xff0c;左边为左子树&#xff0c;右边为右子树。 方法 由思路可知&#xff0c;可以使用递归。递归函数的入口为划分的区间…

day57 判断子序列 不同的子序列 两个字符串的删除操作 编辑距离

题目1 392 判读子序列 题目链接 392 判断子序列 题意 判断字符串s是否为字符串t的子序列 &#xff08;子序列的相对位置在原字符串中不改变&#xff09; 就是求最长公共子序列的长度与字符串s的长度是否相等 动态规划 1&#xff09;确定dp数组及下标i的含义 dp[i][j]…

二十款好用的屏幕录制,绿色绿色好用软件工具,云盘下载

本人收藏多年的屏幕录制工具&#xff0c;绿色的&#xff0c;你懂得的。。。。 二十款好用的屏幕录制&#xff0c;绿色绿色好用软件工具&#xff0c;值得收藏 下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1RPTlFfeap4TGMnDPgCEo-w?pwdmaky 提取码&#xff1…

C#简单工厂模式的实现

using System.Diagnostics.Metrics; using System.Runtime.InteropServices; using static 手写工厂模式.Program;namespace 手写工厂模式 {internal class Program{public interface eats {void eat();}//定义了一个接口public class rice : eats{public void eat() {Console.…

【Next】动态路由、加载 UI 和流式传输

动态路由 动态段作为 params 属性传递给 layout、page、route 和 generateMetadata 函数。 /app/blog/[slug]/page.tsx export default function Page({params}: {params:{slug:string}}) {return <h1>Slug Page -- {params.slug}</h1> };/app/shop/[...slug]/pa…

【C++成长记】C++入门 | 类和对象(上) |类的作用域、类的实例化、类的对象大小的计算、类成员函数的this指针

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、类的作用域 二、类的实例化 三、类对象模型 四、this指针 1、this指针的引出 2 this指针的特…

4.8-4.12算法刷题笔记

刷题 堆1. 堆排序2. 模拟堆 哈希表3. 模拟散列表4. 字符串哈希 DFS5. 排列数字6. n-皇后问题 2. BFS&#xff08;队列&#xff09;7. 字母迷宫8. 滑动谜题 3. 树与图的dfs9. 树的重心 4. 树与图的bfs(最短路)10. 图中点的层次( 无权最短路 ) 5. 拓扑排序11. 课程表 6. 朴素dijk…

C++系列-C++前言

什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序&#xff0c;对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适&#xff0c;为了解决软件危机&#xff0c;20世纪80年代&#xff0c;计算机界提出…

iterations迭代列表

今天总结一下这个列表的迭代 情况1&#xff0c;两个列表的迭代 import itertoolsfor x1,x2 in itertools.product([1, 5, 8], [0.5, 4]):print((x1,x2))结果如下 情况2&#xff08;一个列表的迭代&#xff09; import itertools# for x1,x2 in itertools.product([1, 5, 8…

大数据产品有哪些分类?各类里知名大数据产品都有哪些?

随着互联网技术的持续进步和全球数字化转型的推进&#xff0c;我们正处于一个数据爆炸的时代。在这样的大背景下&#xff0c;大数据已经逐渐崭露头角&#xff0c;成为了推动各行各业发展的关键因素和核心资源。大数据不仅仅是指数据的规模巨大&#xff0c;更重要的是它蕴含的价…

人员聚集监测识别摄像机

随着科技的不断发展&#xff0c;人员聚集监测识别摄像机已经成为了现代社会安全管理的重要工具。这种摄像机能够对人员聚集的情况进行实时监测和识别&#xff0c;帮助相关部门及时发现和处理潜在的安全风险。 人员聚集监测识别摄像机可以通过高清晰度的摄像头和先进的人脸识别技…

Java实现短信发送并校验,华为云短信配合Redis实现发送与校验

Java实现短信发送并校验&#xff0c;华为云短信配合Redis实现发送与校验 安装sms4j和redis <dependency><groupId>org.dromara.sms4j</groupId><artifactId>sms4j-spring-boot-starter</artifactId><version>3.2.1</version> <…

【自研网关系列】请求服务模块和客户端模块实现

&#x1f308;Yu-Gateway&#xff1a;&#xff1a;基于 Netty 构建的自研 API 网关&#xff0c;采用 Java 原生实现&#xff0c;整合 Nacos 作为注册配置中心。其设计目标是为微服务架构提供高性能、可扩展的统一入口和基础设施&#xff0c;承载请求路由、安全控制、流量治理等…

【python图形界面问题解决】wxPython创建图形界面程序,在代码编译器中正常运行,但是打包后却不能运行解决办法

一、问题 使用wxPython创建一个图形界面&#xff0c;在VSCODE中正常运行&#xff0c;但是打包后&#xff0c;却不能运行&#xff0c;只出现一个一闪而过的窗口&#xff0c;这时最需要看看这窗口到底显示了什么内容。这里可以使用录屏软件录制屏幕&#xff0c;这里使用LICEcap小…