JavaWeb中的多數據源開發

從我們接觸Javaweb開始,ssh框架或者ssm等或許是驚歎於框架的強大之處還是自身的迷茫,一直沒有注意到一個問題就是:在我的項目中在spring中所配置的數據源都是指向單一數據庫,都是單數據源,一個指向數據庫的url,數據庫驅動,用戶名密碼等的配置。但是隨着自己工作時間的延長在新公司我接觸到了新的問題。多數據源的配置和使用。

在實際的開發中有很多時候我們是要與其他公司進行合作,有的合作公司會給咱們一系列的數據接口我們只需要做好數據展示等工作,但是有的公司則是會向我們開放一個數據庫的端口,讓我們可以對數據庫進行查詢操作。而且這一部分功能是嵌入在我們原來的系統中的,這時候就會發現我們在我們的項目中用到了兩個數據源,在這之前我們好像對於多數據源的開發毫無經驗。

經過公司大神的指導以及自己的百度查詢結果。get到了這個多數據源開發的技能,首先在spring的配置文件中配置自己的與數據庫進行連接的bean,需要幾個,有幾個配幾個,然後就是需要寫一個類,這個類就是實現多數據源切換的關鍵了。這個類需要繼承spring提供的一個抽象類:org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,然後需要實現其中的一個方法:determineCurrentLookupKey這個方法的作用就是返回要使用的數據源的名稱,注意這個操作是要與將來數據庫中的其他配置聯動的:

<bean id="multipleDataSource" class="com.base.multidb.MyDataSource">
        <property name="defaultTargetDataSource" ref="主數據源"/>
        <property name="targetDataSources">
            <map>
                <entry key=" 主數據源" value-ref="主數據源"/>
   <entry key=" 數據源1" value-ref="數據源1"/>

<entry key=" 數據源2" value-ref="數據源2"/>
            </map>
        </property>
    </bean>

在上面的配置中所用到的三個數據源(與數據庫的連接bean)是自己所配置的存在的,在上面所配置的bean中defaulttargetDataSource代表的是主數據源即默認的數據源,下面的targetDataSources中所屬的map中所配置的就是所有的數據源,有幾個用到幾個就配置幾個,此時就理解了上面自己所寫的實現spring提供的抽象類的方法的操作含義了,那個方法的主要目的就是返回一個所要使用的數據源的名稱,而這個數據源的名稱會去與所配置的map中所有數據源的key進行匹配,一致的數據源就會是這個線程操作所使用到的數據源,通過上面的操作基本上就可以實現多數據源的切換了,自己所實現的那個類其實就是一個數據源的代理對象,然後將這個對象傳遞給sqlsessionfactory即可進行數據庫的相關操作獲取sqlsession操作數據庫了,

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="multipleDataSource"/>
<property name="mapperLocations">
<list>
  <value>classpath:com/mapper/*Mapper.xml</value>
  <value>classpath:com2/mapper/*/*Mapper.xml</value>
</list>
</property>
    </bean>

 而在事物配置上也是,將代理數據源配置到事物中的DataSource即可


  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 

  <property name="dataSource" ref="multipleDataSource" /> 
  </bean>

配置說完了,下面該代理數據源的實現了:


package com.base.multidb;


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class MyChangeDateSource extends AbstractRoutingDataSource{


private static final ThreadLocal<String> datasourceKey = new ThreadLocal<String>();

public static void setDataSource(String useSource){
datasourceKey.set(useSource);
}

@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return datasourceKey.get();
}


}

這個操作沒有多少可說的,因爲我也不是特別懂偷笑,不過還是需要說兩句ThreadLocal是在多線程環境中使用的,創建一個對象只屬於當前線程並在當前線程中共享,set方法就是我們在開發中進行業務邏輯操作之前需要進行數據源切換的一個操作方法。而最後一個方法就是繼承spring提供的抽象類後要求必須實現的一個方法,這個方法中需要進行一個操作,就是返回你所需要使用的數據源的key(在配置文件中有配置)


在接下來說說具體的數據源切換的使用:

首先,這個數據源的切換操作所進行的位置個人認爲是需要在action或者controller中進行的,因爲service中一般都是一些業務邏輯操作一般是需要事物的(比如多數據操作,某一個出錯的數據統一回滾)所以需要在Action中進行切換,如果寫的不對望各位大神留言批判。

具體操作沒什麼:在action中進行數據庫相關操作前加入一行代碼:

MyChangeDateSource.setDataSource(""); 將所要切換的數據源的對應的key作爲參數傳遞進去即可

這樣這個key就保存在ThreadLocal的對象中,對於這個線程來說所使用的的數據源就一直都是正確所需要的數據源(因爲這個controller方法作爲後天的一個部分是在一個多線程環境中可能會有很多個線程都會進行訪問,這樣就將數據源匹配給對應的線程操作不會出現混亂)

最後要提一句:這裏指的多數據源是廣義上的數據源,即一個數據源就是指一個數據庫服務器中的所有數據庫,多數據源是指誇服務器的多個數據庫的操作,如果僅僅是一個數據庫服務器上的多個數據庫的操作的話沒有必要進行多數據源的配置。在進行同源(同一個數據庫服務器)數據庫進行操作的時候只需要在sql語句裏面稍加變動即可,即在寫表的時候不能直接寫表名,而是需要:數據庫  【.】 該庫下的表名 然後進行其他的數據庫操作 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章