Java配置,mysql双数据源 读写分离

2023-10-29


大致思路

创建用于标志数据源的自定义注解
通过配置切面,在操作数据库的方法之前,扫描该方法的注解所配置的数据源名称,将名称存储在一个代表当前线程变量工具类
创建AbstarctRoutingDataSource子类DynamicDataSourc,重写determineCurrentLookupKey()方法,把当前线程变量的工具类存储的数据源名称返回即可。
在spring配置文件中,将多个数据源配置到我们创建的DynamicDataSourc

一、配置双数据源 xml配置文件

 master.driver=com.mysql.cj.jdbc.Driver
 master.url=jdbc:mysql://10.70.20.81:3306/test
 master.username=root
 master.password=root
 ​
 slave.driver=com.mysql.cj.jdbc.Driver
 slave.url=jdbc:mysql://10.70.20.155:3306/test
 slave.username=root
 slave.password=root

 <!-- master数据源 -->
     <beanid="masterDataSource"class="com.alibaba.druid.pool.DruidDataSource">
         <propertyname="driverClassName"value="${master.driver}"></property>
         <propertyname="url"value="${master.url}"></property>
         <propertyname="username"value="${master.username}"></property>
         <propertyname="password"value="${master.password}"></property>
     </bean>
     <!-- slave数据源 -->
     <beanid="slaveDataSource"class="com.alibaba.druid.pool.DruidDataSource">
         <propertyname="driverClassName"value="${slave.driver}"></property>
         <propertyname="url"value="${slave.url}"></property>
         <propertyname="username"value="${slave.username}"></property>
         <propertyname="password"value="${slave.password}"></property>
     </bean>

二、定义用来切库的注解和枚举类

注解定义

 importjava.lang.annotation.ElementType;
 importjava.lang.annotation.Retention;
 importjava.lang.annotation.RetentionPolicy;
 importjava.lang.annotation.Target;
 ​
 @Target({ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 public@interfaceDataSwitch {
     DataTypevalue() defaultDataType.master;
 }

枚举类

 publicenumDataType {
     master("masterDataSource"),slave("slaveDataSource");
     privateStringvalue;
     DataType(Stringname){
         this.value=name;
     }
 ​
     publicStringgetValue() {
         returnvalue;
     }
 ​
     publicvoidsetValue(Stringvalue) {
         this.value=value;
     }
 }

三、定义一个当前线程的变量的工具类,用于设置对应的数据源名称

 public  classDynamicDataSourceHolder {
     privatestaticfinalThreadLocal<String>threadLocal=newThreadLocal<String>();
 ​
     publicstaticStringgetThreadLocal() {
         returnthreadLocal.get();
     }
 ​
     publicstaticvoidsetThreadLocal(Stringname) {
         threadLocal.set(name);
     }
     publicstaticvoidclear(){
         threadLocal.remove();
     }
 }

四、创建AbstractRoutingDataSource的子类,并重写determineCurrentLockupKey方法

 importorg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 ​
 publicclassDynamicDataSourceextendsAbstractRoutingDataSource {
     protectedObjectdetermineCurrentLookupKey() {
 ​
         System.out.println("------------>"+DynamicDataSourceHolder.getThreadLocal());
         returnDynamicDataSourceHolder.getThreadLocal();
     }
 }

五、将多数据源配置到我们创建的DynamicDataSource下

 <beanid="dynamicDataSource"class="com.shen.datasource.DynamicDataSource">
     <propertyname="targetDataSources">
         <mapkey-type="java.lang.String">
             <entrykey="masterDataSource"value-ref="masterDataSource"></entry>
             <entrykey="slaveDataSource"value-ref="slaveDataSource"></entry>
         </map>
     </property>
     <propertyname="defaultTargetDataSource"ref="masterDataSource"></property>
 </bean>

六、配置切面类,在操作数据库方法之前,获取注解配置的数据源名称并返回

 importcom.shen.datasource.DataSwitch;
 importcom.shen.datasource.DataType;
 importcom.shen.datasource.DynamicDataSourceHolder;
 importorg.aspectj.lang.JoinPoint;
 importorg.aspectj.lang.annotation.After;
 importorg.aspectj.lang.annotation.Aspect;
 importorg.aspectj.lang.annotation.Before;
 importorg.aspectj.lang.annotation.Pointcut;
 importorg.springframework.core.annotation.Order;
 importorg.springframework.stereotype.Component;
 ​
 importjava.lang.reflect.Method;
 ​
 @Component
 @Aspect
 @Order(0)
 publicclassDataSourceAspect {
     @Pointcut("execution (* com.shen.service..*(..))")
     publicvoidaspect(){
 ​
     }
     @Before("aspect()")
     publicvoidbefore(JoinPointjoinPoint){
         Class<?>clazz=joinPoint.getTarget().getClass();
         Method[] method=clazz.getMethods();
         DataSwitchdataSwitch=null;
         booleanis=false;
         for(Methodm:method){
             if(m.isAnnotationPresent(DataSwitch.class)){
                 dataSwitch=m.getAnnotation(DataSwitch.class);
                 DynamicDataSourceHolder.setThreadLocal(dataSwitch.value().getValue());
                 is=true;
             }
         }
         if(!is){
             DynamicDataSourceHolder.setThreadLocal(DataType.master.getValue());
         }
     }
     @After("aspect()")
     publicvoidafter(){
         DynamicDataSourceHolder.clear();
     }
 }

七、测试

 @Service
 publicclassUserService {
 ​
     @Autowired
     privateUserMapperuserMapper;
 ​
     @DataSwitch(DataType.master)
     publicIntegerinsertUser(Useruser){
         System.out.println("service--------------------");
         returnuserMapper.insertSelective(user);
     }
 ​
     @DataSwitch(DataType.slave)
     publicList<User>queryAllUsers(){
         returnuserMapper.selectByExample(null);
     }
 }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java配置,mysql双数据源 读写分离 的相关文章

随机推荐

  • python解释器怎么添加_Python解释器的配置

    1 准备工作 安装好Pycharm2017版本 电脑上安装好Python解释器 2 本地解释器配置 配置本地解释器的步骤相对简洁直观 1 单击工具栏中的设置按钮 2 在Settings Preferences对话框中选中 Project I
  • 人脸跟踪开源项目

    https github com xiangdeyizhang FaceTrack ncnn HyperFT https github com qaz734913414 Ncnn FaceTrack Ncnn FaceTrack 基于mtc
  • 数字水印简介

    转自 http baike baidu com view 39205 htm 数字水印 Digital Watermarking 技术是将一些标识信息 即数字水印 直接嵌入数字载体当中 包括多媒体 文档 软件等 或是间接表示 修改特定区域的
  • 经纬度坐标正则验证

    经纬度正则验证表达式 纬度正则表达式 90 至 90 0 8 d 1 d 0 6 90 0 0 6 0 8 d 1 90 经度正则表达式 180 至 180 d 1 9 d 1 0 7 d 0 1 3 d 0 6 d 1 9 d 1 0 7
  • 趣味解C——编程(1)

    前言 题目虽是基础题 旨在用趣味使其乐趣性翻倍 纯属娱乐 解题思路 1 房间 一共n间 我们可以设其为 i 从而定义循环 for i 1 i lt n i 2 服务员 各个服务员都记得自己的使命 ta们没有名字 只知道自己是第几 于是1号最
  • Unity 面试题汇总(三)Unity 基础相关

    Unity 面试题汇总 三 Unity 基础相关 目录 Unity 面试题汇总 三 Unity 基础相关 0 FSM 状态机 HFSM 分层状态机 BT 行为树 的区别 1 什么是协同程序 2 Unity3D中的碰撞器和触发器的区别 3 物
  • 反射概述

    package com kuang reflection 什么叫反射 public class test02 public static void main String args throws ClassNotFoundException
  • SA实战 ·《SpringCloud Alibaba实战》微服务介绍

    微服务化后的问题 一个系统 尤其是大型系统使用微服务架构模式进行搭建和开发时 虽然总体上能够提高研发效率 能够支持更高的并发 也能够提高系统整体的性能和可靠性 以及可维护性 但是在实现细节上还是存在着不少的问题 1 将系统拆分成各个微服务后
  • 御剑的使用

    御剑 1 扫描线程自定义 用户可根据自身电脑的配置来设置调节扫描线程 2 集合DIR扫描 ASP ASPX PHP JSP MDB数据库 包含所有网站脚本路径扫描 3 默认探测200 也就是扫描的网站真实存在的路径文件 我们使用御剑扫描器
  • Java基础8--Scanner类

    Java基础8 Scanner类 java util Scanner 是 Java5 的新特征 我们可以通过 Scanner 类来获取用户的输入 下面是创建 Scanner 对象的基本语法 Scanner s new Scanner Sys
  • 程序员必须知道的十大算法之 快速排序

    快速排序是由东尼 霍尔所发展的一种排序算法 在平均状况下 排序 n 个项目要 nlogn 次比较 在最坏状况下则需要 n2 次比较 但这种状况并不常见 事实上 快速排序通常明显比其他 nlogn 算法更快 因为它的内部循环 innerloo
  • 设计原则与思想:总结课

    文章目录 设计原则与思想 总结课 总结回顾面向对象 设计原则 编程规范 重构技巧等知识点 一 代码质量评判标准 如何评价代码质量的高低 最常用的评价标准有哪几个 如何才能写出高质量的代码 二 面向对象 三 设计原则 四 规范与重构 常见的
  • Win10防止Windows安全中心(Windows Defender)乱删文件

    Windows Defender乱删文件着实让人哭笑不得 还好它还有个排除项 不然只能安个杀毒软件接管它了 点击 开始 点击 设置 开始上面的齿轮图标 打开Windows设置 点击最下面的 更新和安全 点击 Windows安全中心 点击右侧
  • mock详细教程入门这一篇就够了

    1 什么是mock测试 1 png Mock测试就是在测试活动中 对于某些不容易构造或者不容易获取的比较复杂的数据 场景 用一个虚拟的对象 Mock对象 来创建用于测试的测试方法 2 为什么要进行Mock测试 Mock是为了解决不同的单元之
  • day2-ARM处理器概述

    指令集 指令 能够指示处理器执行某种运算的命令称为指令 指令在内存中以机器码 二进制 的方式存在 每一条指令都对应一条汇编 程序是指令的有序集合 指令集 处理器能识别的指令的集合称为指令集 不同架构的处理器指令集不同 指令集是处理器对开发者
  • [915]ElasticSearch设置用户名密码

    1 需要在配置文件中开启x pack验证 修改config目录下面的elasticsearch yml文件 在里面添加如下内容 并重启 xpack security enabled true xpack license self gener
  • javascript练习题之给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

    示例 输入 2 2 1 输出 1 解析一 通过循环来判断每个数出现的次数 然后将次数为1的数输出 var singleNumber function nums 声明一个空对象用于记录 var obj for var i 0 i
  • JVM学习1_ javac编译器源码编译及分析

    javac编译器是纯java代码编写的 用来把 java文件编译成二进制 class文件 一 获取javac编译器源码 github下载jdk源码 jdk源码中包含javac编译器源码 hotspot虚拟机等 下载地址 https gith
  • BGP双平面

    实验要求 1 合理IP地址 2 AS 1 2 3 内部使用OSPF 协议 AS 1 AS 2内部建立全互联的IBGP邻居 AS之间建立全 部的EBGP邻居 3 PC 1 3 5 属于电信的路由 通信时必须使用电信AS 1 PC 2 4 6
  • Java配置,mysql双数据源 读写分离

    大致思路 创建用于标志数据源的自定义注解 通过配置切面 在操作数据库的方法之前 扫描该方法的注解所配置的数据源名称 将名称存储在一个代表当前线程变量工具类 创建AbstarctRoutingDataSource子类DynamicDataSo