1. 程式人生 > >Spring4 + jpa 或者 Mybaits 或者JDBC 動態資料庫切換例項 (1)

Spring4 + jpa 或者 Mybaits 或者JDBC 動態資料庫切換例項 (1)

先說思路及過程.

    之前寫過一篇JPA 多資料來源的,  那個去年第一次接觸.  也是弄了好久.

    最近做一個專案需要jdbc 和  mybatis的整合.  資料來源有6個.   如果按照配置多個sessionFactory來弄不太雅觀.

    正好看到百度發現,專案中本身是有整合多資料來源切換的實現的, 只是沒人注意和不會使用.  

    好了下面來說正題.

   第一.  多資料來源的整理,這個按照自己公司需求配置就好.  這個容易.

            只是在dataSource 中指向了DynamicDataSouce類.  這是動態資料切換的核心.

 .  

DynamicDataSource 類的程式碼如下.  具體原理可百度看其他的文章.  本方法在一般專案中只需要第一個方法就可滿足

. 本類中引入DataSourceContextHolder類實現當前應用中,  使用執行緒的方式來進行資料來源切換.如下

import java.util.Map;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
/**
 * 
* @ClassName: DynamicDataSource 
* @Description: TODO(動態獲取資料來源 關聯app-config) 
* @author ranxing
* @date 2018年5月3日 上午10:41:43 
*
 */
public class DynamicDataSource extends AbstractRoutingDataSource {  
  
    /*  
     * 該方法必須要重寫  方法是為了根據資料庫標示符取得當前的資料庫 
     */  
    @Override  
    public Object determineCurrentLookupKey() {  
        return DataSourceContextHolder.getDataSourceName();  
    }  
  
    @Override  
    public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {  
        super.setDataSourceLookup(dataSourceLookup);  
    }  
  
    @Override  
    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {  
        super.setDefaultTargetDataSource(defaultTargetDataSource);  
    }  
  
    @SuppressWarnings({ "rawtypes", "unchecked" })
@Override  
    public void setTargetDataSources(Map targetDataSources) {  
        super.setTargetDataSources(targetDataSources);  
        //重點  
        super.afterPropertiesSet();  
    }  
  

}

--------------------------

/**
 * 
* @ClassName: DataSourceContextHolder 
* @Description: TODO(通過 TheadLocal 來儲存每個執行緒選擇哪個資料來源的標誌(key):) 
* @author ranxing
* @date 2018年5月3日 上午10:39:38 
*
 */
public class DataSourceContextHolder {  
  
    private static final ThreadLocal<String> contextHolder=new ThreadLocal<String>();  


    public static void setDataSourceType(String dataSourceName){  
        contextHolder.set(dataSourceName);  
    }  
      
    public static String getDataSourceName(){  
        return (String) contextHolder.get();  
    }  
      
    public static void clearDataSourceType(){  
        contextHolder.remove();  
    }  
      
}

---------------------

OK  如上的配置後,   在你原來的專案中,   只要是單一資料來源可以正常使用的情況下.在操作資料庫之前呼叫

 DataSourceContextHolder.setDataSourceType("dataSource1");//dataSource1

方法,  即可切換到指定的資料來源.   這裡的引數是 dataSouce中的key 值.  本人已在jdbc mybatis jpa  的配置中均可正常呼叫.

附一個jpa基本的測試類

                <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-test</artifactId>  
            <version> 3.2.4.RELEASE  </version>  
            <scope>provided</scope>  
</dependency> 

import java.util.List;


import javax.inject.Inject;


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


import cn.com.taiji.repository.CodeRepository;
import cn.com.taiji.util.DataSourceContextHolder;




@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/*-config.xml" })
public class ApplicationTests {


@Inject
CodeRepository codeRepository;


 
@Test
public void runsss() {

DataSourceContextHolder.setDataSourceType("dataSource1");//dataSource1
List<?> list2 = codeRepository.findAllCodes();
 
DataSourceContextHolder.setDataSourceType("centerdb");//dataSource1
List<?> list = codeRepository.findAllCodes();

System.out.println(list.size() +"__" + list2.size());


}

 
 
}