国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊

這篇具有很好參考價值的文章主要介紹了一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1 目標

不在現(xiàn)有查詢代碼邏輯上做任何改動,實現(xiàn)dao維度的數(shù)據(jù)源切換(即表維度)

2 使用場景

節(jié)約bdp的集群資源。接入新的寬表時,通常uat驗證后就會停止集群釋放資源,在對應的查詢服務器uat環(huán)境時需要查詢的是生產(chǎn)庫的表數(shù)據(jù)(uat庫表因為bdp實時任務停止,沒有數(shù)據(jù)落入),只進行服務器配置文件的改動而無需進行代碼的修改變更,即可按需切換查詢的數(shù)據(jù)源。

2.1 實時任務對應的集群資源

一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊

2.2 實時任務產(chǎn)生的數(shù)據(jù)進行存儲的兩套環(huán)境

一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊

2.3 數(shù)據(jù)使用系統(tǒng)的兩套環(huán)境(查詢展示數(shù)據(jù))

一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊

即需要在zhongyouex-bigdata-uat中查詢生產(chǎn)庫的數(shù)據(jù)。

3 實現(xiàn)過程

3.1 實現(xiàn)重點

  1. org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
    spring提供的這個類是本次實現(xiàn)的核心,能夠讓我們實現(xiàn)運行時多數(shù)據(jù)源的動態(tài)切換,但是數(shù)據(jù)源是需要事先配置好的,無法動態(tài)的增加數(shù)據(jù)源。
  2. Spring提供的Aop攔截執(zhí)行的mapper,進行切換判斷并進行切換。

注:另外還有一個就是ThreadLocal類,用于保存每個線程正在使用的數(shù)據(jù)源。

3.2 AbstractRoutingDataSource解析

public abstract class AbstractRoutingDataSource extends AbstractDataSource 
implements InitializingBean{
    @Nullable
    private Map<Object, Object> targetDataSources;

    @Nullable
    private Object defaultTargetDataSource;

    @Override
    public Connection getConnection() throws SQLException {
        return determineTargetDataSource().getConnection();
    }
    protected DataSource determineTargetDataSource() {
        Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
        Object lookupKey = determineCurrentLookupKey();
        DataSource dataSource = this.resolvedDataSources.get(lookupKey);
        if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
            dataSource = this.resolvedDefaultDataSource;
        }
        if (dataSource == null) {
            throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
        }
        return dataSource;
    }
    @Override
    public void afterPropertiesSet() {
        if (this.targetDataSources == null) {
            throw new IllegalArgumentException("Property 'targetDataSources' is required");
        }
        this.resolvedDataSources = new HashMap<>(this.targetDataSources.size());
        this.targetDataSources.forEach((key, value) -> {
            Object lookupKey = resolveSpecifiedLookupKey(key);
            DataSource dataSource = resolveSpecifiedDataSource(value);
            this.resolvedDataSources.put(lookupKey, dataSource);
        });
        if (this.defaultTargetDataSource != null) {
            this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
        }
    }

從上面源碼可以看出它繼承了AbstractDataSource,而AbstractDataSource是javax.sql.DataSource的實現(xiàn)類,擁有getConnection()方法。獲取連接的getConnection()方法中,重點是determineTargetDataSource()方法,它的返回值就是你所要用的數(shù)據(jù)源dataSource的key值,有了這個key值,resolvedDataSource(這是個map,由配置文件中設置好后存入targetDataSources的,通過targetDataSources遍歷存入該map)就從中取出對應的DataSource,如果找不到,就用配置默認的數(shù)據(jù)源。

看完源碼,我們可以知道,只要擴展AbstractRoutingDataSource類,并重寫其中的determineCurrentLookupKey()方法返回自己想要的key值,就可以實現(xiàn)指定數(shù)據(jù)源的切換!

3.3 運行流程

  1. 我們自己寫的Aop攔截Mapper
  2. 判斷當前執(zhí)行的sql所屬的命名空間,然后使用命名空間作為key讀取系統(tǒng)配置文件獲取當前mapper是否需要切換數(shù)據(jù)源
  3. 線程再從全局靜態(tài)的HashMap中取出當前要用的數(shù)據(jù)源
  4. 返回對應數(shù)據(jù)源的connection去做相應的數(shù)據(jù)庫操作

3.4 不切換數(shù)據(jù)源時的正常配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- clickhouse數(shù)據(jù)源   -->
    <bean id="dataSourceClickhousePinpin" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" lazy-init="true">
        <property name="url" value="${clickhouse.jdbc.pinpin.url}" />
    </bean>

    <bean id="singleSessionFactoryPinpin" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- ref直接指向 數(shù)據(jù)源dataSourceClickhousePinpin  -->
<property name="dataSource" ref="dataSourceClickhousePinpin" />
    </bean>

</beans>

3.5 進行動態(tài)數(shù)據(jù)源切換時的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- clickhouse數(shù)據(jù)源 1  -->
    <bean id="dataSourceClickhousePinpin" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" lazy-init="true">
        <property name="url" value="${clickhouse.jdbc.pinpin.url}" />
    </bean>
<!-- clickhouse數(shù)據(jù)源 2  -->
    <bean id="dataSourceClickhouseOtherPinpin" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" lazy-init="true">
        <property name="url" value="${clickhouse.jdbc.other.url}" />
    </bean>
 <!-- 新增配置 封裝注冊的兩個數(shù)據(jù)源到multiDataSourcePinpin里 -->
 <!-- 對應的key分別是 defaultTargetDataSource和targetDataSources-->
    <bean id="multiDataSourcePinpin" class="com.zhongyouex.bigdata.common.aop.MultiDataSource">
      <!-- 默認使用的數(shù)據(jù)源-->
<property name="defaultTargetDataSource" ref="dataSourceClickhousePinpin"></property>
        <!-- 存儲其他數(shù)據(jù)源,對應源碼中的targetDataSources -->
<property name="targetDataSources">
            <!-- 該map即為源碼中的resolvedDataSources-->
            <map>
                <!-- dataSourceClickhouseOther 即為要切換的數(shù)據(jù)源對應的key -->
<entry key="dataSourceClickhouseOther" value-ref="dataSourceClickhouseOtherPinpin"></entry>
            </map>
        </property>
    </bean>

    <bean id="singleSessionFactoryPinpin" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- ref指向封裝后的數(shù)據(jù)源multiDataSourcePinpin  -->
<property name="dataSource" ref="multiDataSourcePinpin" />
    </bean>
</beans>

核心是AbstractRoutingDataSource,由spring提供,用來動態(tài)切換數(shù)據(jù)源。我們需要繼承它,來進行操作。這里我們自定義的com.zhongyouex.bigdata.common.aop.MultiDataSource就是繼承了AbstractRoutingDataSource

package com.zhongyouex.bigdata.common.aop;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
 * @author: cuizihua
 * @description: 動態(tài)數(shù)據(jù)源
 * @date: 2021/9/7 20:24
 * @return
 */
public class MultiDataSource extends AbstractRoutingDataSource {

    /* 存儲數(shù)據(jù)源的key值,InheritableThreadLocal用來保證父子線程都能拿到值。
     */
    private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();

    /**
     * 設置dataSourceKey的值
     *
     * @param dataSource
     */
    public static void setDataSourceKey(String dataSource) {
        dataSourceKey.set(dataSource);
    }

    /**
     * 清除dataSourceKey的值
     */
    public static void toDefault() {
        dataSourceKey.remove();
    }

    /**
     * 返回當前dataSourceKey的值
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return dataSourceKey.get();
    }
}

3.6 AOP代碼

package com.zhongyouex.bigdata.common.aop;
import com.zhongyouex.bigdata.common.util.LoadUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;

/**
 * 方法攔截  粒度在mapper上(對應的sql所屬xml)
 * @author cuizihua
 * @desc 切換數(shù)據(jù)源
 * @create 2021-09-03 16:29
 **/
@Slf4j
public class MultiDataSourceInterceptor {
//動態(tài)數(shù)據(jù)源對應的key
    private final String otherDataSource = "dataSourceClickhouseOther";

    public void beforeOpt(JoinPoint mi) {
//默認使用默認數(shù)據(jù)源
        MultiDataSource.toDefault();
        //獲取執(zhí)行該方法的信息
        MethodSignature signature = (MethodSignature) mi.getSignature();
        Method method = signature.getMethod();
        String namespace = method.getDeclaringClass().getName();
//本項目命名空間統(tǒng)一的規(guī)范為xxx.xxx.xxxMapper
        namespace = namespace.substring(namespace.lastIndexOf(".") + 1);
//這里在配置文件配置的屬性為xxxMapper.ck.switch=1 or 0  1表示切換
        String isOtherDataSource = LoadUtil.loadByKey(namespace, "ck.switch");
        if ("1".equalsIgnoreCase(isOtherDataSource)) {
            MultiDataSource.setDataSourceKey(otherDataSource);
            String methodName = method.getName();
        }
    }
}

3.7 AOP代碼邏輯說明

通過org.aspectj.lang.reflect.MethodSignature可以獲取對應執(zhí)行sql的xml空間名稱,拿到sql對應的xml命名空間就可以獲取配置文件中配置的屬性決定該xml是否開啟切換數(shù)據(jù)源了。

3.8 對應的aop配置

<!--動態(tài)數(shù)據(jù)源-->
<bean id="multiDataSourceInterceptor" class="com.zhongyouex.bigdata.common.aop.MultiDataSourceInterceptor" ></bean>
<!--將自定義攔截器注入到spring中-->
<aop:config proxy-target-class="true" expose-proxy="true">
    <aop:aspect ref="multiDataSourceInterceptor">
        <!--切入點,也就是你要監(jiān)控哪些類下的方法,這里寫的是DAO層的目錄,表達式需要保證只掃描dao層-->
        <aop:pointcut id="multiDataSourcePointcut" expression="execution(*  com.zhongyouex.bigdata.clickhouse..*.*(..)) "/>
        <!--在該切入點使用自定義攔截器-->
        <aop:before method="beforeOpt" pointcut-ref="multiDataSourcePointcut" />
    </aop:aspect>
</aop:config>

以上就是整個實現(xiàn)過程,希望能幫上有需要的小伙伴

作者:京東物流 崔子華

來源:京東云開發(fā)者社區(qū)文章來源地址http://www.zghlxwxcb.cn/news/detail-496088.html

到了這里,關于一種實現(xiàn)Spring動態(tài)數(shù)據(jù)源切換的方法 | 京東云技術團隊的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 實例講解Spring boot動態(tài)切換數(shù)據(jù)源

    摘要: 本文模擬一下在主庫查詢訂單信息查詢不到的時候,切換數(shù)據(jù)源去歷史庫里面查詢。 本文分享自華為云社區(qū)《springboot動態(tài)切換數(shù)據(jù)源》,作者:小陳沒煩惱 。 在公司的系統(tǒng)里,由于數(shù)據(jù)量較大,所以配置了多個數(shù)據(jù)源,它會根據(jù)用戶所在的地區(qū)去查詢那一個數(shù)據(jù)庫

    2024年02月06日
    瀏覽(26)
  • mybatisplus快速實現(xiàn)動態(tài)數(shù)據(jù)源切換

    1.背景 ? 通常一個系統(tǒng)只需要連接一個數(shù)據(jù)庫就可以了。但是在企業(yè)應用的開發(fā)中往往會和其他子系統(tǒng)交互,特別是對于一些數(shù)據(jù)實時性要求比較高的數(shù)據(jù),我們就需要做實時連接查詢,而不是做同步。這個時候就需要用到多數(shù)據(jù)源。 ? 舉個簡單的例子某企業(yè)要做訂單網(wǎng)上訂

    2024年02月06日
    瀏覽(25)
  • 【工作小札】利用動態(tài)數(shù)據(jù)源實現(xiàn)Sass的一種思路(內含完整代碼示例)

    【工作小札】利用動態(tài)數(shù)據(jù)源實現(xiàn)Sass的一種思路(內含完整代碼示例)

    ?這里是第七人格的博客?小七,歡迎您的到來~? ??系列專欄:【工作小札】?? ??本篇內容: 利用動態(tài)數(shù)據(jù)源實現(xiàn)Sass化?? ??本篇收錄完整代碼地址:https://gitee.com/diqirenge/sheep-web-demo/tree/master/sheep-web-demo-dynamicDataSource?? 針對Sass多租戶,業(yè)內有許多解決方案。一般來說

    2023年04月20日
    瀏覽(23)
  • 使用mybatis和dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫

    記錄 :415 場景 :使用mybatis和dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫。 版本 :JDK 1.8,Spring?Boot 2.6.3,dynamic-datasource-spring-boot-starter-3.3.2,mybatis-3.5.9。 源碼 :https://github.com/baomidou/dynamic-datasource-spring-boot-starter dynamic-datasource-spring-boot-starter :一個基于springboot的快

    2023年04月19日
    瀏覽(23)
  • 使用dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源操作數(shù)據(jù)庫(MyBatis-3.5.9)

    記錄 :383 場景 :使用dynamic-datasource-spring-boot-starter動態(tài)切換數(shù)據(jù)源,使用MyBatis操作數(shù)據(jù)庫。提供三種示例:一,使用@DS注解作用到類上。二,使用@DS注解作用到方法上。三,不使用注解,使用DynamicDataSourceContextHolder類在方法內靈活切換不同數(shù)據(jù)源。 源碼: https://github.com/

    2024年01月20日
    瀏覽(25)
  • 基于注解切換、Hikari實現(xiàn)的SpringBoot動態(tài)數(shù)據(jù)源(支持JNDI)

    先說效果,要實現(xiàn)方法級別注解切換當前數(shù)據(jù)源,不設置注解時走默認數(shù)據(jù)源,同時支持JNDI源。 Spring框架中存在一個抽象類 AbstractRoutingDataSource ,他是一個可以動態(tài)選擇當前DataSource的路由類,我們就是要從這里入手,重新實現(xiàn)數(shù)據(jù)源的切換選擇邏輯。然后借助注解和切面,

    2024年02月08日
    瀏覽(33)
  • springboot整合多數(shù)據(jù)源的配置以及動態(tài)切換數(shù)據(jù)源,注解切換數(shù)據(jù)源

    springboot整合多數(shù)據(jù)源的配置以及動態(tài)切換數(shù)據(jù)源,注解切換數(shù)據(jù)源

    在許多應用程序中,可能需要使用多個數(shù)據(jù)庫或數(shù)據(jù)源來處理不同的業(yè)務需求。Spring Boot提供了簡便的方式來配置和使用多數(shù)據(jù)源,使開發(fā)人員能夠輕松處理多個數(shù)據(jù)庫連接。如果你的項目中可能需要隨時切換數(shù)據(jù)源的話,那我這篇文章可能能幫助到你 ??:這里對于pom文件

    2024年02月10日
    瀏覽(33)
  • springboot dynamic-datasource 實現(xiàn)動態(tài)切換數(shù)據(jù)源-多租戶-配置文件切換-基于dynamic-datasource

    1、實現(xiàn)動態(tài)切換數(shù)據(jù)源 2、實現(xiàn)配置多數(shù)據(jù)源 3、實現(xiàn)讀寫分離也可以用多數(shù)據(jù)源方式 4、選擇 dynamic-datasource集成了很多ORM的框架,其中,使用比較多的是druid,但有一些東西開始收費了 druid也可以自行配置,配置多了點 目前版本只支持單一位置加載數(shù)據(jù)源(只能從配置文件或

    2024年02月09日
    瀏覽(18)
  • SpringBoot——動態(tài)數(shù)據(jù)源(多數(shù)據(jù)源自動切換)

    SpringBoot——動態(tài)數(shù)據(jù)源(多數(shù)據(jù)源自動切換)

    日常的業(yè)務開發(fā)項目中只會配置一套數(shù)據(jù)源,如果需要獲取其他系統(tǒng)的數(shù)據(jù)往往是通過調用接口, 或者是通過第三方工具比如kettle將數(shù)據(jù)同步到自己的數(shù)據(jù)庫中進行訪問。 但是也會有需要在項目中引用多數(shù)據(jù)源的場景。比如如下場景: 自研數(shù)據(jù)遷移系統(tǒng),至少需要新、老兩

    2024年02月16日
    瀏覽(18)
  • SpringBoot動態(tài)切換數(shù)據(jù)源

    SpringBoot動態(tài)切換數(shù)據(jù)源

    ? Spring提供一個DataSource實現(xiàn)類用于動態(tài)切換數(shù)據(jù)源—— AbstractRoutingDataSource pom.xml 大概的項目結構 注意:這兩個事務管理器,并不能處理分布式事務 鏈接:https://pan.baidu.com/s/1ymxeKYkI-cx7b5nTQX0KWQ? 提取碼:6bii? --來自百度網(wǎng)盤超級會員V4的分享? ? ? ? ? ? ? ??

    2024年02月06日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包