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

Springboot如何設(shè)置多數(shù)據(jù)源,隨時(shí)切換

 更新時(shí)間:2024年04月01日 15:57:56   作者:快樂敲代碼  
這篇文章主要介紹了Springboot如何設(shè)置多數(shù)據(jù)源,隨時(shí)切換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

需求

接到一個(gè)任務(wù),把一個(gè)數(shù)據(jù)庫里面的數(shù)據(jù)定時(shí)導(dǎo)入到另外的數(shù)據(jù)庫中

但是又不允許我們通過binlog+canal同步,所以考慮起一個(gè)微服務(wù)充當(dāng)同步腳本的作用

且配置多數(shù)據(jù)庫,并且支持隨時(shí)切換

環(huán)境

  • 1、mysql多個(gè)庫
  • 2、mysql+postgresql

思路

spring框架本身支持多數(shù)據(jù)源,我們查看他的定義

Spring的多數(shù)據(jù)源支持—AbstractRoutingDataSource,AbstractRoutingDataSource定義了抽象的determineCurrentLookupKey方法,子類實(shí)現(xiàn)此方法,來確定要使用的數(shù)據(jù)源

看下下面它的源碼:

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
	 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;
	}

        // 確定當(dāng)前要使用的數(shù)據(jù)源
        protected abstract Object determineCurrentLookupKey();
}

所以我們只要寫一個(gè)自定義類去繼承上面這個(gè)AbstractRoutingDataSource類,并重寫determineCurrentLookupKey 方法即可

操作

包如下:

一、多個(gè)庫都是mysql類型

pom依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>db-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>db-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1、配置文件application.yml

#端口
server.port: 7788
spring.application.name: bddemo

# mysql
spring.datasource:
  driver-class-name: com.mysql.cj.jdbc.Driver
  #數(shù)據(jù)庫1
  db1:
    jdbc-url: jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
  #數(shù)據(jù)庫2
  db2:
    jdbc-url: jdbc:mysql://127.0.0.1:3306/db2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456

# mybatis
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: ccom.example.demo.*.entity

2、配置類

1) DataSourceConfig 數(shù)據(jù)庫配置類:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 數(shù)據(jù)庫配置
* @date 2022/5/19
*/
@Configuration
public class DataSourceConfig {

    /**
     * 數(shù)據(jù)源1
     * spring.datasource.db1:application.properteis中對(duì)應(yīng)屬性的前綴
     * @return
     */
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource dataSourceOne() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 數(shù)據(jù)源2
     * spring.datasource.db2:application.properteis中對(duì)應(yīng)屬性的前綴
     * @return
     */
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSourceTwo() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 動(dòng)態(tài)數(shù)據(jù)源: 通過AOP在不同數(shù)據(jù)源之間動(dòng)態(tài)切換
     * @return
     */
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默認(rèn)數(shù)據(jù)源
        dynamicDataSource.setDefaultTargetDataSource(dataSourceOne());
        // 配置多數(shù)據(jù)源
        Map<Object, Object> dsMap = new HashMap<>();
        dsMap.put("db1", dataSourceOne());
        dsMap.put("db2", dataSourceTwo());

        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
    }

    /**
     * 配置多數(shù)據(jù)源后IOC中存在多個(gè)數(shù)據(jù)源了,事務(wù)管理器需要重新配置,不然器不知道選擇哪個(gè)數(shù)據(jù)源
     * 事務(wù)管理器此時(shí)管理的數(shù)據(jù)源將是動(dòng)態(tài)數(shù)據(jù)源dynamicDataSource
     * 配置@Transactional注解
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }
}

2) DynamicDataSource 動(dòng)態(tài)數(shù)據(jù)源類:

import com.example.demo.utils.DataSourceUtil;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
 * 動(dòng)態(tài)數(shù)據(jù)源類
 * @date 2022/2/11
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceUtil.getDB();
    }
}

3、切換工具類:DataSourceUtil

/**
* 數(shù)據(jù)源切換工具
 * @date 2022/5/19
*/
public class DataSourceUtil {
    /**
     * 默認(rèn)數(shù)據(jù)源
     */
    public static final String DEFAULT_DS = "db1";
    /**
    *  數(shù)據(jù)源屬于一個(gè)公共的資源
    *  采用ThreadLocal可以保證在多線程情況下線程隔離
    */
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    /**
     * 設(shè)置數(shù)據(jù)源名
     * @param dbType
     */
    public static void setDB(String dbType) {
        contextHolder.set(dbType);
    }

    /**
     * 獲取數(shù)據(jù)源名
     * @return
     */
    public static String getDB() {
        return (contextHolder.get());
    }

    /**
     * 清除數(shù)據(jù)源名
     */
    public static void clearDB() {
        contextHolder.remove();
    }
}

4、啟動(dòng)

(1)啟動(dòng)類中配置移除默認(rèn)的數(shù)據(jù)庫配置類

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

//移除默認(rèn)數(shù)據(jù)庫配置類
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DbDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DbDemoApplication.class, args);
    }

}

(2)測(cè)試

結(jié)果

  • db1庫

  • db2庫

二、一個(gè)是mysql一個(gè)是postgresql

1、pom依賴新增

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>

2、配置文件application.yml

#端口
server.port: 7788
spring.application.name: bddemo

# mysql
spring.datasource:
  #數(shù)據(jù)庫1
  db1:
    driver-class-name: com.mysql.cj.jdbc.Driver
    jdbc-url: jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: root
    password: 123456
  #數(shù)據(jù)庫2
  db2:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    jdbc-url: jdbc:mysql://127.0.0.1:3306/db2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
#    username: root
#    password: 123456
    driver-class-name: org.postgresql.Driver
    jdbc-url: jdbc:postgresql://127.0.0.1:5432/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: postgres
    password: 123456

# mybatis
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: ccom.example.demo.*.entity

注意:

之前都是mysql的庫,所以驅(qū)動(dòng)在上面

現(xiàn)在因?yàn)閿?shù)據(jù)庫的產(chǎn)品不一樣,所以驅(qū)動(dòng)類名稱放在下面單獨(dú)配置(有些人真完全不會(huì)變通,哎)

3、測(cè)試

插入:pg數(shù)據(jù)庫的主鍵自增mybatis還有點(diǎn)難搞,我們直接配置id插入

  • mysql:

  • pg:

  • 查詢:

總結(jié)

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

相關(guān)文章

  • Java標(biāo)識(shí)接口的使用方法

    Java標(biāo)識(shí)接口的使用方法

    在本篇文章中小編給大家分享了關(guān)于Java標(biāo)識(shí)接口的使用方法和教程內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-01-01
  • Java之單例設(shè)計(jì)模式示例詳解

    Java之單例設(shè)計(jì)模式示例詳解

    這篇文章主要介紹了Java之單例設(shè)計(jì)模式示例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot一個(gè)非常蛋疼的無法啟動(dòng)的問題解決

    SpringBoot一個(gè)非常蛋疼的無法啟動(dòng)的問題解決

    這篇文章主要介紹了SpringBoot一個(gè)非常蛋疼的無法啟動(dòng)的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java中\(zhòng)n和\r區(qū)別

    Java中\(zhòng)n和\r區(qū)別

    本文主要介紹了Java中\(zhòng)n和\r區(qū)別。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Java ShardingJDBC實(shí)戰(zhàn)演練

    Java ShardingJDBC實(shí)戰(zhàn)演練

    Sharding-JDBC 采用在 JDBC 協(xié)議層擴(kuò)展分庫分表,是一個(gè)以 jar 形式提供服務(wù)的輕量級(jí)組件,其核心思路是小而美地完成最核心的事情
    2021-11-11
  • vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果

    vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果

    這篇文章主要介紹了vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java實(shí)現(xiàn)租車管理系統(tǒng)

    Java實(shí)現(xiàn)租車管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)租車管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • vscode 配置java環(huán)境并調(diào)試運(yùn)行的詳細(xì)過程

    vscode 配置java環(huán)境并調(diào)試運(yùn)行的詳細(xì)過程

    這篇文章主要介紹了vscode 配置java環(huán)境并調(diào)試運(yùn)行的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • Java實(shí)現(xiàn)圖片比率縮放

    Java實(shí)現(xiàn)圖片比率縮放

    這篇文章主要為大家詳細(xì)介紹了Java通過Thumbnails實(shí)現(xiàn)圖片比率縮放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 淺談java中六大時(shí)間類的使用和區(qū)別

    淺談java中六大時(shí)間類的使用和區(qū)別

    下面小編就為大家?guī)硪黄獪\談java中六大時(shí)間類的使用和區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01

最新評(píng)論