最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

需求

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

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

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

環(huán)境

  • 1、mysql多個庫
  • 2、mysql+postgresql

思路

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

Spring的多數(shù)據(jù)源支持—AbstractRoutingDataSource,AbstractRoutingDataSource定義了抽象的determineCurrentLookupKey方法,子類實現(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();
}

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

操作

包如下:

一、多個庫都是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中對應(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中對應(yīng)屬性的前綴
     * @return
     */
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource dataSourceTwo() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 動態(tài)數(shù)據(jù)源: 通過AOP在不同數(shù)據(jù)源之間動態(tài)切換
     * @return
     */
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默認數(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中存在多個數(shù)據(jù)源了,事務(wù)管理器需要重新配置,不然器不知道選擇哪個數(shù)據(jù)源
     * 事務(wù)管理器此時管理的數(shù)據(jù)源將是動態(tài)數(shù)據(jù)源dynamicDataSource
     * 配置@Transactional注解
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dynamicDataSource());
    }
}

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

import com.example.demo.utils.DataSourceUtil;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
 * 動態(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 {
    /**
     * 默認數(shù)據(jù)源
     */
    public static final String DEFAULT_DS = "db1";
    /**
    *  數(shù)據(jù)源屬于一個公共的資源
    *  采用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、啟動

(1)啟動類中配置移除默認的數(shù)據(jù)庫配置類

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

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

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

}

(2)測試

結(jié)果

  • db1庫

  • db2庫

二、一個是mysql一個是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ū)動在上面

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

3、測試

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

  • mysql:

  • pg:

  • 查詢:

總結(jié)

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

相關(guān)文章

  • Eclipse中創(chuàng)建Web項目最新方法(2023年)

    Eclipse中創(chuàng)建Web項目最新方法(2023年)

    在Java開發(fā)人員中,最常用的開發(fā)工具應(yīng)該就是Eclipse,下面這篇文章主要給大家介紹了關(guān)于Eclipse中創(chuàng)建Web項目2023年最新的方法,需要的朋友可以參考下
    2023-09-09
  • Java 內(nèi)存模型 (JMM) 與 volatile 底層實現(xiàn)

    Java 內(nèi)存模型 (JMM) 與 volatile 底層實現(xiàn)

    這篇文章詳細介紹了Java中的volatile關(guān)鍵字,從硬件底層到JVM規(guī)范,逐步講解了它的核心原理,包括可見性和禁止重排序,文章還探討了volatile的使用場景、常見誤區(qū)以及在實際工作中的應(yīng)用,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • IDEA配置JavaFX全過程

    IDEA配置JavaFX全過程

    從Java11起,Java不再內(nèi)置JavaFX,在Java17項目中,需手動配置開發(fā)環(huán)境,添加JavaFX庫路徑,并設(shè)置運行參數(shù)指向本地路徑
    2025-09-09
  • Java?基于Hutool實現(xiàn)DES加解密示例詳解

    Java?基于Hutool實現(xiàn)DES加解密示例詳解

    這篇文章主要介紹了Java基于Hutool實現(xiàn)DES加解密,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • JAVA強密碼校驗算法示例代碼

    JAVA強密碼校驗算法示例代碼

    最近系統(tǒng)需要做用戶密碼升級,增加強密碼校驗,密碼長度,復(fù)雜度等等,這篇文章主要介紹了JAVA強密碼校驗算法的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-07-07
  • 淺談java+內(nèi)存分配及變量存儲位置的區(qū)別

    淺談java+內(nèi)存分配及變量存儲位置的區(qū)別

    下面小編就為大家?guī)硪黄獪\談java+內(nèi)存分配及變量存儲位置的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • SpringBoot中的事務(wù)配置管理詳解

    SpringBoot中的事務(wù)配置管理詳解

    這篇文章主要介紹了SpringBoot中的事務(wù)配置管理詳解,Spring Boot 默認的事務(wù)規(guī)則是遇到運行異常(RuntimeException)和程序錯誤(Error)才會回滾,但是拋出SQLException就無法回滾了,需要的朋友可以參考下
    2024-01-01
  • java反射之獲取類的信息方法(推薦)

    java反射之獲取類的信息方法(推薦)

    下面小編就為大家?guī)硪黄猨ava反射之獲取類的信息方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • idea中使用(Revert Commit)圖解

    idea中使用(Revert Commit)圖解

    這篇文章主要介紹了idea中使用(Revert Commit)圖解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • eclipse下搭建hibernate5.0環(huán)境的步驟(圖文)

    eclipse下搭建hibernate5.0環(huán)境的步驟(圖文)

    這篇文章主要介紹了eclipse下搭建hibernate5.0環(huán)境的步驟(圖文),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論

红桥区| 嘉兴市| 象州县| 定日县| 惠来县| 阿拉善左旗| 明水县| 敦煌市| 肇州县| 珲春市| 昭平县| 南江县| 太康县| 广宁县| 威海市| 靖江市| 巴林右旗| 乌拉特中旗| 高青县| 长葛市| 高青县| 礼泉县| 英山县| 霞浦县| 竹北市| 大新县| 湘乡市| 仙居县| 宾阳县| 尼木县| 汪清县| 阿瓦提县| 虹口区| 油尖旺区| 奉贤区| 渭源县| 祥云县| 南宫市| 文安县| 岫岩| 古交市|