欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot利用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問(wèn)題

 更新時(shí)間:2025年03月17日 15:47:14   作者:一個(gè)有女朋友的程序員  
dynamic-datasource-spring-boot-starter 是一個(gè)用于在 Spring Boot 項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的工具,下面我們看看如何使用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問(wèn)題吧

概要

自己閑暇時(shí)間想實(shí)現(xiàn)一個(gè)多租戶(hù)平臺(tái),需要實(shí)現(xiàn)數(shù)據(jù)分離,動(dòng)態(tài)配置生成數(shù)據(jù)源,憑著自己的感覺(jué)搭建了一套簡(jiǎn)單的方案

dynamic-datasource-spring-boot-starter 是一個(gè)用于在 Spring Boot 項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的工具,這里主要通過(guò)這個(gè)工具實(shí)現(xiàn)在系統(tǒng)運(yùn)行中創(chuàng)建數(shù)據(jù)庫(kù),生成數(shù)據(jù)庫(kù)連接。

整體架構(gòu)構(gòu)想

【創(chuàng)建數(shù)據(jù)源】使用DefaultDataSourceCreator類(lèi)下的createDataSource方法創(chuàng)建數(shù)據(jù)源。

【存儲(chǔ)數(shù)據(jù)源】使用DynamicRoutingDataSource方法的addDataSource方法以鍵值對(duì)存儲(chǔ)數(shù)據(jù)源。

【切換數(shù)據(jù)源】使用**@DS**注解動(dòng)態(tài)切換數(shù)據(jù)源。

操作步驟

創(chuàng)建數(shù)據(jù)源

創(chuàng)建數(shù)據(jù)源方法大致如下,主要就是創(chuàng)建數(shù)據(jù)庫(kù)的參數(shù)配置,讓生成器生成數(shù)據(jù)源。

        //默認(rèn)使用Mysql8.0,并且連接mysql數(shù)據(jù)庫(kù)表,通過(guò)這個(gè)連接創(chuàng)建新的數(shù)據(jù)庫(kù)數(shù)據(jù)
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        // 數(shù)據(jù)源參數(shù)配置
        DataSourceProperty dataSourceProperty = new DataSourceProperty();
        //固定使用mysql8
        String dbClassType = "com.mysql.cj.jdbc.Driver";
        String dbUrl = String.format("jdbc:mysql://%s:%s/%s?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8", dbIp, dbPort, dbName);
        //這里使用IP進(jìn)行區(qū)分
        dataSourceProperty.setPoolName(dbIp);
        dataSourceProperty.setUsername(userName);
        dataSourceProperty.setPassword(passWord);
        dataSourceProperty.setUrl(dbUrl);
        dataSourceProperty.setDriverClassName(dbClassType);
        // 數(shù)據(jù)源全部懶加載,避免一次性聲明過(guò)多連接
        dataSourceProperty.setLazy(true);
        // 生成數(shù)據(jù)源
        DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
		//最后存儲(chǔ)到ds中,后面可以用個(gè)不同的key去連接不同的數(shù)據(jù)源
		ds.addDataSource(dbIp,dataSource);

后面在調(diào)用不同數(shù)據(jù)庫(kù)的時(shí)候只需要使用**@DS**注解,代碼如下:

    /**
     * 調(diào)用不同的數(shù)據(jù)連接生成新的數(shù)據(jù)庫(kù)
     * @param onlySignIp 
     * @param dbName
     * @return
     */
    @DS(value = "#onlySignIp")
    public int createDataSource(String onlySignIp,@Param("dbName")String dbName);

切換數(shù)據(jù)源

一開(kāi)始我覺(jué)得這樣就可以直接在系統(tǒng)中自定義創(chuàng)建數(shù)據(jù)庫(kù),dynamic-datasource底層在初始化加載的時(shí)候會(huì)生成一條責(zé)任鏈,一共為三個(gè)節(jié)點(diǎn)分別為DsHeaderProcessor、DsSessionProcessor、DsSpelExpressionProcessor分別對(duì)應(yīng)#header、#session和spel表達(dá)式,源碼如下:

    @Bean
    @ConditionalOnMissingBean
    public DsProcessor dsProcessor(BeanFactory beanFactory) {
        DsHeaderProcessor headerProcessor = new DsHeaderProcessor();
        DsSessionProcessor sessionProcessor = new DsSessionProcessor();
        DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
        spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
        headerProcessor.setNextProcessor(sessionProcessor);
        sessionProcessor.setNextProcessor(spelExpressionProcessor);
        return headerProcessor;
    }

在這里 根據(jù)底層代碼理論上來(lái)說(shuō)是不會(huì)應(yīng)該有問(wèn)題的,好像是用它自定義的責(zé)任鏈不行,這里我就自己重寫(xiě)了這條責(zé)任鏈(也就自己復(fù)制源代碼將他注入到spring容器中),然后在重寫(xiě)DsSpelExpressionProcessor,通過(guò)spel表達(dá)式來(lái)選擇數(shù)據(jù)源。

public class DsSpelExpressionProcessor extends DsProcessor {

    /**
     * 參數(shù)發(fā)現(xiàn)器
     */
    private static final ParameterNameDiscoverer NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
    /**
     * Express語(yǔ)法解析器
     */
    private static final ExpressionParser PARSER = new SpelExpressionParser();
    /**
     * 解析上下文的模板
     * 對(duì)于默認(rèn)不設(shè)置的情況下,從參數(shù)中取值的方式 #param1
     * 設(shè)置指定模板 ParserContext.TEMPLATE_EXPRESSION 后的取值方式: #{#param1}
     * issues: https://github.com/baomidou/dynamic-datasource-spring-boot-starter/issues/199
     */
    private ParserContext parserContext = new ParserContext() {

        @Override
        public boolean isTemplate() {
            return false;
        }

        @Override
        public String getExpressionPrefix() {
            return null;
        }

        @Override
        public String getExpressionSuffix() {
            return null;
        }
    };
    private BeanResolver beanResolver;

    @Override
    public boolean matches(String key) {
        return true;
    }

    @Override
    public String doDetermineDatasource(MethodInvocation invocation, String key) {
        Object[] arguments = invocation.getArguments();
        StandardEvaluationContext context = new StandardEvaluationContext(arguments);
        //默認(rèn)使用第一個(gè)參數(shù)
        String replace = key.replace("#", "");
        context.setVariable(replace,arguments[0]);
        final Object value = PARSER.parseExpression(key, parserContext).getValue(context);
        return value == null ? null : value.toString();
    }


    public void setParserContext(ParserContext parserContext) {
        this.parserContext = parserContext;
    }

    public void setBeanResolver(BeanResolver beanResolver) {
        this.beanResolver = beanResolver;
    }
}

這樣配合@DS注解就可以實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)切換了。

后續(xù)問(wèn)題

在需要切換數(shù)據(jù)源的情況下,將對(duì)應(yīng)數(shù)據(jù)源Key信息作為Mapper第一個(gè)參數(shù)傳遞

例如:

    /**
     * 調(diào)用不同的數(shù)據(jù)連接生成新的數(shù)據(jù)庫(kù)
     * @param onlySignIp 
     * @param dbName
     * @return
     */
    @DS(value = "#onlySignIp")
    public int createDataSource(String onlySignIp,@Param("dbName")String dbName);

在切換數(shù)據(jù)源的情況下必須要加上**@DS**注解,而且還必須將對(duì)應(yīng)數(shù)據(jù)源的Key作為第一個(gè)參數(shù)進(jìn)行傳入

小結(jié)

通過(guò)對(duì) dynamic-datasource-spring-boot-starter 的剖析,我們簡(jiǎn)單的實(shí)現(xiàn)了自定義創(chuàng)建數(shù)據(jù)源,切換數(shù)據(jù)源的操作

到此這篇關(guān)于SpringBoot利用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問(wèn)題的文章就介紹到這了,更多相關(guān)SpringBoot多數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RestTemplate發(fā)送請(qǐng)求時(shí)Cookie的影響及注意事項(xiàng)說(shuō)明

    RestTemplate發(fā)送請(qǐng)求時(shí)Cookie的影響及注意事項(xiàng)說(shuō)明

    這篇文章主要介紹了RestTemplate發(fā)送請(qǐng)求時(shí)Cookie的影響及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2023-07-07
  • 解決eclipse中console控制選項(xiàng)不見(jiàn)了的方法

    解決eclipse中console控制選項(xiàng)不見(jiàn)了的方法

    eclipse是一款用于編譯java語(yǔ)言的程序,利用這款軟件我們可以制作很多有趣的小程序,也可以制作一些大型的軟件項(xiàng)目,有的用戶(hù)在使用eclipse的時(shí)候會(huì)遇到console消失的情況,所以本文給大家介紹了解決eclipse中console控制選項(xiàng)不見(jiàn)了的方法,需要的朋友可以參考下
    2024-03-03
  • Java?設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解原型模式

    Java?設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解原型模式

    原型模式是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式,今天通過(guò)本文給大家介紹下Java 原型設(shè)計(jì)模式,感興趣的朋友一起看看吧
    2022-04-04
  • Java查看本機(jī)端口是否被占用源碼

    Java查看本機(jī)端口是否被占用源碼

    這篇文章主要介紹了Java查看本機(jī)端口是否被占用的主要原理,并結(jié)合具體實(shí)例給出了操作方法,需要的朋友可以參考下
    2017-09-09
  • 判斷以逗號(hào)分隔的字符串中是否包含某個(gè)數(shù)的實(shí)例

    判斷以逗號(hào)分隔的字符串中是否包含某個(gè)數(shù)的實(shí)例

    下面小編就為大家?guī)?lái)一篇判斷以逗號(hào)分隔的字符串中是否包含某個(gè)數(shù)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • 解決spring-boot使用logback的大坑

    解決spring-boot使用logback的大坑

    這篇文章主要介紹了解決spring-boot使用logback的大坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能實(shí)例

    JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能實(shí)例

    因自己負(fù)責(zé)的項(xiàng)目中需要實(shí)現(xiàn)文件上傳,所以下面下面這篇文章主要給大家介紹了關(guān)于JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • JAVA異常處理捕獲與拋出原理解析

    JAVA異常處理捕獲與拋出原理解析

    這篇文章主要介紹了JAVA異常處理捕獲與拋出原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Maven+Tomcat8 實(shí)現(xiàn)自動(dòng)化部署的方法

    Maven+Tomcat8 實(shí)現(xiàn)自動(dòng)化部署的方法

    本篇文章主要介紹了Maven+Tomcat8 實(shí)現(xiàn)自動(dòng)化部署的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java中解壓縮文件的方法詳解(通用)

    Java中解壓縮文件的方法詳解(通用)

    在軟件開(kāi)發(fā)和數(shù)據(jù)處理領(lǐng)域,文件的解壓縮和壓縮是常見(jiàn)的任務(wù),下面這篇文章主要給大家介紹了關(guān)于Java中解壓縮文件的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06

最新評(píng)論