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

Spring AbstractRoutingDatasource 動態(tài)數(shù)據(jù)源的實例講解

 更新時間:2021年07月22日 09:29:47   作者:夢想畫家  
本文介紹如何使用 Spring AbstractRoutingDatasource 基于上下文動態(tài)切換數(shù)據(jù)源,因此我們會讓查找數(shù)據(jù)源邏輯獨立于數(shù)據(jù)訪問之外

Spring AbstractRoutingDatasource 動態(tài)數(shù)據(jù)源

數(shù)據(jù)源上下文

AbstractRoutingDatasource 需要信息決定路由到那個數(shù)據(jù)源,該信息我們稱為上下文??梢允腥魏螌ο螅旅媸纠覀兪褂妹杜e ClientDatabase 作為上下文:

public enum ClientDatabase {
    CLIENT_A, CLIENT_B
}

值得注意的是,實際中上下文可以是任何有意義的領(lǐng)域?qū)ο蟆H?Environment 定義上下文,在這種上下文中枚舉可以包括 PRODUCTION, DEVELOPMENT, and TESTING.

上下文持有者 ( ContextHolder )

上下文持有者實現(xiàn)是存儲當(dāng)前上下文的容器,如 ThreadLocal 對象。除了包括上下文引用外,還應(yīng)該包括set , get , clear 靜態(tài)方法,AbstractRoutingDatasource 將查詢 ContextHolder 獲得 上下文,然后使用上下文查找實際的數(shù)據(jù)源。

這里最重要的是使用 ThreadLocal ,讓上下文綁定只當(dāng)前執(zhí)行線程。使用這種方法就是為了保障當(dāng)數(shù)據(jù)訪問邏輯跨多個數(shù)據(jù)源使用事務(wù):

public class ClientDatabaseContextHolder {
    private static ThreadLocal<ClientDatabase> CONTEXT  = new ThreadLocal<>();
    public static void set(ClientDatabase clientDatabase) {
        Assert.notNull(clientDatabase, "clientDatabase cannot be null");
        CONTEXT.set(clientDatabase);
    }
    public static ClientDatabase getClientDatabase() {
        return CONTEXT.get();
    }
    public static void clear() {
        CONTEXT.remove();
    }
}

數(shù)據(jù)源路由器

下面定義 ClientDataSourceRouter 繼承 AbstractRoutingDataSource. 重寫方法 determineCurrentLookupKey ,查詢 ClientDatabaseContextHolder 獲得當(dāng)前 上下文。AbstractRoutingDataSource 幫我們處理了其他邏輯,僅了解它透明地返回了合適的數(shù)據(jù)源:

public class ClientDataSourceRouter extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return ClientDatabaseContextHolder.getClientDatabase();
    }
}

配置

下面利用Map上下文存儲DataSource對象,用于配置 AbstractRoutingDataSource 。當(dāng)然也可以指定缺省數(shù)據(jù)源,當(dāng)沒有設(shè)定上下文時選擇缺省數(shù)據(jù)源。

@Configuration
public class RoutingTestConfiguration {
    @Bean
    public ClientService clientService() {
        return new ClientService(new ClientDao(clientDatasource()));
    }
 
    @Bean
    public DataSource clientDatasource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        DataSource clientADatasource = clientADatasource();
        DataSource clientBDatasource = clientBDatasource();
        targetDataSources.put(ClientDatabase.CLIENT_A, clientADatasource);
        targetDataSources.put(ClientDatabase.CLIENT_B, clientBDatasource);
        ClientDataSourceRouter clientRoutingDatasource  = new ClientDataSourceRouter();
        clientRoutingDatasource.setTargetDataSources(targetDataSources);
        clientRoutingDatasource.setDefaultTargetDataSource(clientADatasource);        
        return clientRoutingDatasource;
    }
    // ...
}

我們可以使用不同方式的數(shù)據(jù)源,但典型場景時運行時創(chuàng)建,或使用JNDI方式查找。下面定義示例的Dao類,它依賴動態(tài)數(shù)據(jù)源進行實例化:

public class ClientDao {
    private static final String SQL_GET_CLIENT_NAME = "select name from client";
    private final JdbcTemplate jdbcTemplate;
    public ClientDao(DataSource datasource) {
        this.jdbcTemplate = new JdbcTemplate(datasource);
    }
    public String getClientName() {
        return this.jdbcTemplate.query(SQL_GET_CLIENT_NAME, rowMapper).get(0);
    }
    private static RowMapper<String> rowMapper = (rs, rowNum) -> {
        return rs.getString("name");
    };
}

使用動態(tài)數(shù)據(jù)源

實際使用時,首先設(shè)置上下文,然后再執(zhí)行業(yè)務(wù)操作。我們定義業(yè)務(wù)層,其中業(yè)務(wù)方法包括上下文作為參數(shù)。在執(zhí)行業(yè)務(wù)之前設(shè)置上下文,調(diào)用之后清除上下文:

public class ClientService {
    private final ClientDao clientDao;
    public ClientService(ClientDao clientDao) {
        this.clientDao = clientDao;
    }
    public String getClientName(ClientDatabase clientDb) {
        ClientDatabaseContextHolder.set(clientDb);
        String clientName = this.clientDao.getClientName();
        ClientDatabaseContextHolder.clear();
        return clientName;
    }
}

總結(jié)

本文通過示例解釋如何使用 Spring AbstractRoutingDataSource 實現(xiàn) 動態(tài)數(shù)據(jù)源切換。

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

相關(guān)文章

  • Java中提供synchronized后為什么還要提供Lock

    Java中提供synchronized后為什么還要提供Lock

    這篇文章主要介紹了Java中提供synchronized后為什么還要提供Lock,在Java中提供了synchronized關(guān)鍵字來保證只有一個線程能夠訪問同步代碼塊,下文更多相關(guān)資料需要的小伙伴可以參考一下
    2022-03-03
  • Java使用Jdom讀取xml解析實例

    Java使用Jdom讀取xml解析實例

    這篇文章主要介紹了Java使用Jdom讀取xml解析,以實例形式較為詳細的分析了Jdom操作XML文件實現(xiàn)讀取操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Go并發(fā)編程中使用channel的方法

    Go并發(fā)編程中使用channel的方法

    本文給大家介紹Go并發(fā)編程中使用channel的方法,通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • SpringBoot應(yīng)用啟動內(nèi)置Tomcat的過程源碼分析

    SpringBoot應(yīng)用啟動內(nèi)置Tomcat的過程源碼分析

    這篇文章主要介紹了SpringBoot應(yīng)用啟動內(nèi)置Tomcat的過程分析,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • 一個簡單的Spring容器初始化流程詳解

    一個簡單的Spring容器初始化流程詳解

    這篇文章主要給大家介紹了一個簡單的Spring容器初始化流程的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解SpringBoot?Start組件開發(fā)之記錄接口日志信息

    詳解SpringBoot?Start組件開發(fā)之記錄接口日志信息

    這篇文章主要為大家介紹了SpringBoot-Start組件開發(fā)之記錄接口日志信息詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 簡單了解Spring中常用工具類

    簡單了解Spring中常用工具類

    這篇文章主要介紹了簡單了解Spring中常用工具類,非常全面,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Java中Lambda表達式的使用詳細教程

    Java中Lambda表達式的使用詳細教程

    這篇文章將通過示例為大家詳細展示Java中Lambda表達式的用法,同時也會介紹Lambda的相關(guān)知識,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • Java設(shè)計模式之java備忘錄模式詳解

    Java設(shè)計模式之java備忘錄模式詳解

    這篇文章主要介紹了JAVA設(shè)計模式之備忘錄模式,簡單說明了備忘錄模式的概念、原理并結(jié)合實例形式分析了java備忘錄模式的具體定義及使用方法,需要的朋友可以參考下
    2021-09-09
  • java.lang.OutOfMemoryError: Metaspace異常解決的方法

    java.lang.OutOfMemoryError: Metaspace異常解決的方法

    這篇文章主要介紹了java.lang.OutOfMemoryError: Metaspace異常解決的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論