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

SpringBoot框架DataSource多數(shù)據(jù)源配置方式

 更新時(shí)間:2024年07月11日 15:00:54   作者:胖虎不吃生菜  
這篇文章主要介紹了SpringBoot框架DataSource多數(shù)據(jù)源配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

新增數(shù)據(jù)源填入xml文件

這里使用的是新搭建的一個(gè)架子,依賴(lài)什么的 就自己Maven工廠(chǎng)去下載吧

我是按照若依的架子搭建的,之前弄過(guò)一次,失敗了哈哈哈

進(jìn)入正題

1、導(dǎo)入依賴(lài)

2、在配置文件中添加數(shù)據(jù)源信息

3、新建 自定義注解 DataSource

4、新建 DynamicDataSource

繼承Spring boot提供的AbstractRoutingDataSource 根據(jù)用戶(hù)定義的規(guī)則選擇當(dāng)前的數(shù)據(jù)源 

它的抽象方法 determineCurrentLookupKey() 決定使用哪個(gè)數(shù)據(jù)源。

全部代碼

/**
 * 動(dòng)態(tài)數(shù)據(jù)源
 * @program: LanAn
 * @description: DynamicDataSource
 * @author: LanAn
 * @create: 2022-08-17 15:33
 **/
public class DynamicDataSource extends AbstractRoutingDataSource {
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    /**
    * 根據(jù)用戶(hù)定義的規(guī)則選擇當(dāng)前的數(shù)據(jù)源]
    * @return: java.lang.Object
    * @Author: LanAn
    * @Date: 2022/8/17 0017
    */
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceType();
    }
}

5、新建DynamicDataSourceContextHolder做動(dòng)態(tài)數(shù)據(jù)源切換處理

public class DynamicDataSourceContextHolder {

    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);

    /**
     * 使用ThreadLocal維護(hù)變量,ThreadLocal為每個(gè)使用該變量的線(xiàn)程提供獨(dú)立的變量副本,
     *  所以每一個(gè)線(xiàn)程都可以獨(dú)立地改變自己的副本,而不會(huì)影響其它線(xiàn)程所對(duì)應(yīng)的副本。
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    /**
     * 設(shè)置數(shù)據(jù)源的變量
     */
    public static void setDataSourceType(String dsType)
    {
        log.info("切換到{}數(shù)據(jù)源", dsType);
        CONTEXT_HOLDER.set(dsType);
    }

    /**
     * 獲得數(shù)據(jù)源的變量
     */
    public static String getDataSourceType()
    {
        return CONTEXT_HOLDER.get();
    }

    /**
     * 清空數(shù)據(jù)源變量
     */
    public static void clearDataSourceType()
    {
        CONTEXT_HOLDER.remove();
    }
}

6、新建DataSourceType添加對(duì)應(yīng)的數(shù)據(jù)庫(kù)枚舉

新增數(shù)據(jù)源的話(huà) 在下方繼續(xù)添加枚舉

全部代碼

public enum DataSourceType {
    /**
     * 主庫(kù)
     */
    MASTER,

    /**
     * 從庫(kù)
     */
    SLAVE
}

7、新增DruidConfig配置類(lèi)配置讀配置源方法

有多個(gè)數(shù)據(jù)源可以在下方照葫蘆畫(huà)瓢 哈哈哈

配置類(lèi)全部代碼

public class DruidConfig {
    /**
    * 主庫(kù)數(shù)據(jù)源
    * @Param: [druidProperties]
    * @return: javax.sql.DataSource
    * @Author: LanAn
    * @Date: 2022/8/17 0017
    */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource(DruidProperties druidProperties) {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    /**
    * 從庫(kù)數(shù)據(jù)源
    * @Param: [druidProperties]
    * @return: javax.sql.DataSource
    * @Author: LanAn
    * @Date: 2022/8/17 0017
    */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties) {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }

    /**
     * 設(shè)置數(shù)據(jù)源
     *
     * @param targetDataSources 備選數(shù)據(jù)源集合
     * @param sourceName        數(shù)據(jù)源名稱(chēng)
     * @param beanName          bean名稱(chēng)
     */
    public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName) {
        try {
            DataSource dataSource = SpringUtils.getBean(beanName);
            targetDataSources.put(sourceName, dataSource);
        } catch (Exception e) {
        }
    }

    /**
     * 去除監(jiān)控頁(yè)面底部的廣告
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    @Bean
    @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) {
        // 獲取web監(jiān)控頁(yè)面的參數(shù)
        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
        // 提取common.js的配置路徑
        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
        final String filePath = "support/http/resources/js/common.js";
        // 創(chuàng)建filter進(jìn)行過(guò)濾
        Filter filter = new Filter() {
            @Override
            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
            }

            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                    throws IOException, ServletException {
                chain.doFilter(request, response);
                // 重置緩沖區(qū),響應(yīng)頭不會(huì)被重置
                response.resetBuffer();
                // 獲取common.js
                String text = Utils.readFromResource(filePath);
                // 正則替換banner, 除去底部的廣告信息
                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
                text = text.replaceAll("powered.*?shrek.wang</a>", "");
                response.getWriter().write(text);
            }

            @Override
            public void destroy() {
            }
        };
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
 }

嘶~~~~少了倆配置,補(bǔ)到后邊吧

8、新建 DruidProperties druid配置屬性

@Configuration
public class DruidProperties {

    @Value("${spring.datasource.druid.initialSize}")
    private int initialSize;

    @Value("${spring.datasource.druid.minIdle}")
    private int minIdle;

    @Value("${spring.datasource.druid.maxActive}")
    private int maxActive;

    @Value("${spring.datasource.druid.maxWait}")
    private int maxWait;

    @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
    private int maxEvictableIdleTimeMillis;

    @Value("${spring.datasource.druid.validationQuery}")
    private String validationQuery;

    @Value("${spring.datasource.druid.testWhileIdle}")
    private boolean testWhileIdle;

    @Value("${spring.datasource.druid.testOnBorrow}")
    private boolean testOnBorrow;

    @Value("${spring.datasource.druid.testOnReturn}")
    private boolean testOnReturn;

    public DruidDataSource dataSource(DruidDataSource datasource) {
        /** 配置初始化大小、最小、最大 */
        datasource.setInitialSize(initialSize);
        datasource.setMaxActive(maxActive);
        datasource.setMinIdle(minIdle);

        /** 配置獲取連接等待超時(shí)的時(shí)間 */
        datasource.setMaxWait(maxWait);

        /** 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 */
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

        /** 配置一個(gè)連接在池中最小、最大生存的時(shí)間,單位是毫秒 */
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);

        /**
         * 用來(lái)檢測(cè)連接是否有效的sql,要求是一個(gè)查詢(xún)語(yǔ)句,常用select 'x'。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會(huì)起作用。
         */
        datasource.setValidationQuery(validationQuery);
        /** 建議配置為true,不影響性能,并且保證安全性。申請(qǐng)連接的時(shí)候檢測(cè),如果空閑時(shí)間大于timeBetweenEvictionRunsMillis,執(zhí)行validationQuery檢測(cè)連接是否有效。 */
        datasource.setTestWhileIdle(testWhileIdle);
        /** 申請(qǐng)連接時(shí)執(zhí)行validationQuery檢測(cè)連接是否有效,做了這個(gè)配置會(huì)降低性能。 */
        datasource.setTestOnBorrow(testOnBorrow);
        /** 歸還連接時(shí)執(zhí)行validationQuery檢測(cè)連接是否有效,做了這個(gè)配置會(huì)降低性能。 */
        datasource.setTestOnReturn(testOnReturn);
        return datasource;
    }
}

9、多數(shù)據(jù)源處理

/**
 * @program: LanAn
 * 多數(shù)據(jù)源處理
 * @description: DataSourceAspect
 * @author: LanAn
 * @create: 2022-08-17 14:21
 **/
@Aspect
@Order(1)
@Component
public class DataSourceAspect {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(com.lanan.common.annotation.DataSource)"
            + "|| @within(com.lanan.common.annotation.DataSource)")
    public void dsPointCut() {

    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        DataSource dataSource = getDataSource(point);

        if (StringUtils.isNotNull(dataSource)) {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }

        try {
            return point.proceed();
        } finally {
            // 銷(xiāo)毀數(shù)據(jù)源 在執(zhí)行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 獲取需要切換的數(shù)據(jù)源
     */
    public DataSource getDataSource(ProceedingJoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource)) {
            return dataSource;
        }

        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}

10、配置完成 使用方法

在實(shí)現(xiàn)類(lèi)上直接使用@DataSource注解

可以在方法上指定使用某個(gè)數(shù)據(jù)源

完成!?。。。。。?/p>

總結(jié)

ok!到這里就完成了,啟動(dòng)頁(yè)沒(méi)有報(bào)錯(cuò)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java中的File文件類(lèi)以及FileDescriptor文件描述類(lèi)

    詳解Java中的File文件類(lèi)以及FileDescriptor文件描述類(lèi)

    在Java中File類(lèi)可以用來(lái)新建文件和目錄對(duì)象,而FileDescriptor類(lèi)則被用來(lái)表示文件或目錄的可操作性,接下來(lái)我們就來(lái)詳解Java中的File文件類(lèi)以及FileDescriptor文件描述類(lèi)
    2016-06-06
  • Java中RocketMQ的延遲消息詳解

    Java中RocketMQ的延遲消息詳解

    這篇文章主要介紹了Java中RocketMQ的延遲消息詳解,RocketMQ是一款開(kāi)源的分布式消息系統(tǒng),基于高可用分布式集群技術(shù),提供低延時(shí)的、高可靠、萬(wàn)億級(jí)容量、靈活可伸縮的消息發(fā)布與訂閱服務(wù),需要的朋友可以參考下
    2023-09-09
  • SpingMvc復(fù)雜參數(shù)傳收總結(jié)

    SpingMvc復(fù)雜參數(shù)傳收總結(jié)

    這篇文章主要為大家介紹了SpingMvc復(fù)雜參數(shù)傳收總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Spring如何解決單例bean線(xiàn)程不安全的問(wèn)題

    Spring如何解決單例bean線(xiàn)程不安全的問(wèn)題

    這篇文章主要介紹了Spring如何解決單例bean線(xiàn)程不安全的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Maven中央倉(cāng)庫(kù)地址配置大全

    Maven中央倉(cāng)庫(kù)地址配置大全

    這篇文章主要介紹了Maven中央倉(cāng)庫(kù)地址配置大全,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 詳解Spring 中如何控制2個(gè)bean中的初始化順序

    詳解Spring 中如何控制2個(gè)bean中的初始化順序

    本篇文章主要介紹了Spring 中如何控制2個(gè)bean中的初始化順序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 為什么wait和notify必須放在synchronized中使用

    為什么wait和notify必須放在synchronized中使用

    這篇文章主要介紹了為什么wait和notify必須放在synchronized中使用,文章圍繞主題的相關(guān)問(wèn)題展開(kāi)詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考以參考一下
    2022-05-05
  • Java利用HttpClient模擬POST表單操作應(yīng)用及注意事項(xiàng)

    Java利用HttpClient模擬POST表單操作應(yīng)用及注意事項(xiàng)

    本文主要介紹JAVA中利用HttpClient模擬POST表單操作,希望對(duì)大家有所幫助。
    2016-04-04
  • Mybatis?連接mysql數(shù)據(jù)庫(kù)底層運(yùn)行的原理分析

    Mybatis?連接mysql數(shù)據(jù)庫(kù)底層運(yùn)行的原理分析

    這篇文章主要介紹了Mybatis?連接mysql數(shù)據(jù)庫(kù)底層運(yùn)行的原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot?mybatis-plus使用json字段實(shí)戰(zhàn)指南

    SpringBoot?mybatis-plus使用json字段實(shí)戰(zhàn)指南

    在現(xiàn)代應(yīng)用開(kāi)發(fā)中經(jīng)常會(huì)使用JSON格式存儲(chǔ)和傳輸數(shù)據(jù),為了便捷地處理數(shù)據(jù)庫(kù)中的JSON字段,MyBatis-Plus提供了強(qiáng)大的JSON處理器,這篇文章主要給大家介紹了關(guān)于SpringBoot?mybatis-plus使用json字段的相關(guān)資料,需要的朋友可以參考下
    2024-01-01

最新評(píng)論