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

SpringBoot多數(shù)據(jù)源解決方案:dynamic-datasource-spring-boot-starter

 更新時間:2025年03月28日 08:31:04   作者:一個有女朋友的程序員  
本文主要介紹了SpringBoot多數(shù)據(jù)源解決方案,使用dynamic-datasource-spring-boot-starter實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

概要

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

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

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

  • 【創(chuàng)建數(shù)據(jù)源】使用DefaultDataSourceCreator類下的createDataSource方法創(chuàng)建數(shù)據(jù)源。
  • 【存儲數(shù)據(jù)源】使用DynamicRoutingDataSource方法的addDataSource方法以鍵值對存儲數(shù)據(jù)源。
  • 【切換數(shù)據(jù)源】使用**@DS**注解動態(tài)切換數(shù)據(jù)源。

操作步驟

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

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

        //默認使用Mysql8.0,并且連接mysql數(shù)據(jù)庫表,通過這個連接創(chuàng)建新的數(shù)據(jù)庫數(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進行區(qū)分
        dataSourceProperty.setPoolName(dbIp);
        dataSourceProperty.setUsername(userName);
        dataSourceProperty.setPassword(passWord);
        dataSourceProperty.setUrl(dbUrl);
        dataSourceProperty.setDriverClassName(dbClassType);
        // 數(shù)據(jù)源全部懶加載,避免一次性聲明過多連接
        dataSourceProperty.setLazy(true);
        // 生成數(shù)據(jù)源
        DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty);
		//最后存儲到ds中,后面可以用個不同的key去連接不同的數(shù)據(jù)源
		ds.addDataSource(dbIp,dataSource);

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

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

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

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

    @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ù)底層代碼理論上來說是不會應(yīng)該有問題的,好像是用它自定義的責(zé)任鏈不行,這里我就自己重寫了這條責(zé)任鏈(也就自己復(fù)制源代碼將他注入到spring容器中),然后在重寫DsSpelExpressionProcessor,通過spel表達式來選擇數(shù)據(jù)源。

public class DsSpelExpressionProcessor extends DsProcessor {

    /**
     * 參數(shù)發(fā)現(xiàn)器
     */
    private static final ParameterNameDiscoverer NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
    /**
     * Express語法解析器
     */
    private static final ExpressionParser PARSER = new SpelExpressionParser();
    /**
     * 解析上下文的模板
     * 對于默認不設(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);
        //默認使用第一個參數(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注解就可以實現(xiàn)數(shù)據(jù)源的動態(tài)切換了。

后續(xù)問題

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

例如:

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

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

小結(jié)

通過對 dynamic-datasource-spring-boot-starter 的剖析,我們簡單的實現(xiàn)了自定義創(chuàng)建數(shù)據(jù)源,切換數(shù)據(jù)源的操作,后續(xù)問題如果大家有對應(yīng)的解決方法,希望評論告知

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

相關(guān)文章

  • Java 語言中Object 類和System 類詳解

    Java 語言中Object 類和System 類詳解

    Object 是 Java 類庫中的一個特殊類,也是所有類的父類。今天通過本文給大家介紹java object類的簡單概念及常用方法,需要的朋友參考下吧
    2021-07-07
  • springboot與vue實現(xiàn)簡單的CURD過程詳析

    springboot與vue實現(xiàn)簡單的CURD過程詳析

    這篇文章主要介紹了springboot與vue實現(xiàn)簡單的CURD過程詳析,圍繞springboot與vue的相關(guān)資料展開實現(xiàn)CURD過程的過程介紹,需要的小伙伴可以參考一下
    2022-01-01
  • 詳解簡單基于spring的redis配置(單機和集群模式)

    詳解簡單基于spring的redis配置(單機和集群模式)

    這篇文章主要介紹了詳解簡單基于spring的redis配置(單機和集群模式),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • Spring Junit測試找不到SpringJUnit4ClassRunner.class的解決

    Spring Junit測試找不到SpringJUnit4ClassRunner.class的解決

    這篇文章主要介紹了Spring Junit測試找不到SpringJUnit4ClassRunner.class的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java通過反射注解賦值的方法詳解

    Java通過反射注解賦值的方法詳解

    這篇文章主要為大家詳細介紹了Java語言如何通過反射實現(xiàn)注解賦值,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下
    2022-07-07
  • java使用gzip實現(xiàn)文件解壓縮示例

    java使用gzip實現(xiàn)文件解壓縮示例

    這篇文章主要介紹了java使用gzip實現(xiàn)文件解壓縮示例,需要的朋友可以參考下
    2014-03-03
  • Java套接字(Socket)網(wǎng)絡(luò)編程入門

    Java套接字(Socket)網(wǎng)絡(luò)編程入門

    這篇文章主要介紹了Java套接字(Socket)網(wǎng)絡(luò)編程入門,Socket可以理解為是對TCP/IP協(xié)議的抽象,需要的朋友可以參考下
    2015-10-10
  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • MyBatis-Plus?中?typeHandler?的使用實例詳解

    MyBatis-Plus?中?typeHandler?的使用實例詳解

    本文介紹了在MyBatis-Plus中如何使用typeHandler處理json格式字段和自定義typeHandler,通過使用JacksonTypeHandler,可以簡單實現(xiàn)將實體類字段轉(zhuǎn)換為json格式存儲,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • spring boot ajax跨域的兩種方式

    spring boot ajax跨域的兩種方式

    java語言在多數(shù)時,會作為一個后端語言,為前端的php,node.js等提供API接口。這篇文章主要介紹了spring boot ajax跨域的兩種方式,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-05-05

最新評論