1. 程式人生 > >springmvc+mybatis 配置多資料來源相互切換

springmvc+mybatis 配置多資料來源相互切換

         近日因為專案需求,需要動態切換資料來源,就稍稍做了下研究,理解的不深,有不對的地方還望高人指點。

        直接貼上程式碼:

  resource.xml

 	<bean id="sqlSessionFactory" class="com.hotent.core.mybatis.SqlSessionFactoryFactoryBean">
        <property name="configLocation" value="classpath:/conf/configuration.xml"/>
        <property name="mapperLocations" >
        	<list>
        		<value>classpath:/com/hotent/*/maper/*.map.xml</value>
        	</list>
        </property>
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean id="dataSource" class="com.hotent.core.db.DynamicDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry key="dataSourceOrg" value-ref="dataSourceOrg" />
				<entry key="defaultDataSource" value-ref="defaultDataSource" />
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="defaultDataSource" />
	</bean>
	 <bean id="dataSourceOrg"  class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >  
		<property name="driverClassName" value="${jdbc.driverClassNameOrg}"/>
		<property name="url" value="${jdbc.urlOrg}"/>
		<property name="username" value="${jdbc.usernameOrg}"/>
		<property name="password" value="${jdbc.passwordOrg}"/>
		 
	</bean>
    
    <bean id="defaultDataSource"  class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" >  
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		 
	</bean>
	<pre name="code" class="plain">

我這裡配置資料庫連線池用的是 com.alibaba.druid.pool.DruidDataSource 。下面的DynamicDataSource是實現AbstractRoutingDataSource 的 。

public class DynamicDataSource extends AbstractRoutingDataSource {

	/**
	 * 取得當前使用那個資料來源。
	 */
	@Override
	protected Object determineCurrentLookupKey() {
		
		return DbContextHolder.getDbType();  
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		return null;
	}
	//設定資料來源集合.
    @Override
    public void setTargetDataSources(Map targetDataSources) {
        super.setTargetDataSources(targetDataSources);
    }
}

DbContextHolder.java
public class DbContextHolder
{
	private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
	 public static final String DATA_SOURCE_DEFAULT = "defaultDataSource";  
	 public static final String DATA_SOURCE_ORG = "dataSourceOrg";  
	/**
	 * 設定當前資料庫。
	 * @param dbType
	 */
	/* @Resource
	 private DynamicDataSource dds;*/
	public static void setDbType(String dbType)
	{
		contextHolder.set(dbType);
		
	}
	/**
	 * 取得當前資料來源。
	 * @return
	 */
	public static String getDbType()
	{
		String str = (String) contextHolder.get();
		if (null == str || "".equals(str))
			str = "1";
		return str;
	}
	
	/**
	 * 清除上下文資料
	 */
	public static void clearDbType()
	{
		contextHolder.remove();
	}
	
	
}
這裡兩個常量就是兩個資料來源的id.以後增加資料來源,這裡也要增加。setDbType就用做後面切換資料時候設定當前資料來源。當完成操作以後要呼叫clearDbType方法恢復預設資料來源。

test.java

public class test {

	 
	@Test
	public void test() {
		ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[] {"conf/app-context.xml"});
		IAuthenticate service = (IAuthenticate)cxt.getBean("iAuthenticate");
		SysOrg org = new SysOrg();
		org.setOrgId(123456789L);
		org.setOrgName("測試資料來源");
		org.setAreaid(1L);
		//service.add(org);
		List<ISysOrg> sysorg_ =service.getAllOrgs();
		 JSONArray json =JSONArray.fromObject(sysorg_);
		 System.out.println(json.toString());
		DbContextHolder.setDbType(DbContextHolder.DATA_SOURCE_ORG);//切換資料來源
		List<ISysOrg> sysorg_1 =service.getAllOrgs();
		 JSONArray json1 =JSONArray.fromObject(sysorg_1);
		 System.out.println(json1.toString());
		 DbContextHolder.clearDbType();//恢復預設資料來源
		 
	}

}

執行,切換成功。

中間遇到過一個問題,一直沒有解決,還不知道是為什麼,我用org.logicalcobwebs.proxool.ProxoolDataSource配置資料庫連線池的時候資料來源無法切換,後來改成com.alibaba.druid.pool.DruidDataSource、com.hotent.core.db.DynamicDataSource都可以。暫時還沒查到原因。還望高人指點一下。