來源:http://itssh.cn/post/946.html
Spring 數據源默認只支持配置一個,如果需要配置多數據源,可在操作數據源之前動態改變數據源鏈接。
案例:
jdbc.properties:
#oracle
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
jdbc.username=用戶名
jdbc.password=密碼
#mysql
jdbc.driverClassName2=com.mysql.jdbc.Driver
jdbc.url2=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username2=用戶名
jdbc.password2=密碼
Spring application.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<!--注解方式 -->
<context:annotation-config />
<context:component-scan base-package="cn.itssh.*" />
<!-- jdbc連接配置 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 數據源配置1 -->
<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource"
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}" />
<!-- 連接池啟動時的初始值 -->
<property name="initialSize" value="1" />
<!-- 連接池的最大值 -->
<property name="maxActive" value="200" />
<!-- 最大空閑值.當經過一個高峰時間后,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止 -->
<property name="maxIdle" value="20" />
<!-- 最小空閑值.當空閑的連接數少于閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請 -->
<property name="minIdle" value="1" />
<property name="maxWait" value="30000" />
<property name="defaultAutoCommit" value="false" />
</bean>
<!-- 數據源2 -->
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName2}" />
<property name="url" value="${jdbc.url2}" />
<property name="username" value="${jdbc.username2}" />
<property name="password" value="${jdbc.password2}" />
<!-- 連接池啟動時的初始值 -->
<property name="initialSize" value="1" />
<!-- 連接池的最大值 -->
<property name="maxActive" value="200" />
<!-- 最大空閑值.當經過一個高峰時間后,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止 -->
<property name="maxIdle" value="20" />
<!-- 最小空閑值.當空閑的連接數少于閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請 -->
<property name="minIdle" value="1" />
<property name="maxWait" value="30000" />
<property name="defaultAutoCommit" value="false" />
</bean>
<!-- 動態數據源 -->
<bean id="dataSource" class="cn.itssh.dataSource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1"></entry>
<entry value-ref="dataSource2" key="dataSource2"></entry>
</map>
</property>
<!-- 默認使用ds1的數據源 -->
<property name="defaultTargetDataSource" ref="dataSource1"/>
</bean>
<!-- 事務 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<!-- jdbc 連接配置 -->
</beans>
動態獲取數據源類 DynamicDataSource.java:
package cn.itssh.dataSource;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @ClassName: DynamicDataSource.java
* @Description: 多數據源
* @author: SM(sm0210@qq.com)
* @date: 2017年6月7日 下午6:08:40
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 多數據源
*/
@Override
protected Object determineCurrentLookupKey() {
//
return DataSourceContextHolder.getDataSource();
}
/**
*
*/
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
存放數據源線程類 DataSourceContextHolder.java
package cn.itssh.dataSource;
/**
* @ClassName: DataSourceContextHolder.java
* @Description: TODO
* @author: SM(sm0210@qq.com)
* @date: 2017年6月7日 下午6:10:20
*/
public class DataSourceContextHolder {
//
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
*
* @param dataSource
*/
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
/**
* @return
*/
public static String getDataSource() {
return ((String) contextHolder.get());
}
/**
*/
public static void clearDataSource() {
contextHolder.remove();
}
}
查詢數據接口 DataSourceDao.java
package cn.itssh.dao;
import java.util.List;
import java.util.Map;
/**
* @ClassName: DataSourceDao.java
* @Description: TODO
* @author: SM(sm@yitong.com.cn)
* @date: 2017年6月14日 下午5:47:21
*/
public interface DataSourceDao {
/**
* 多數據源測試
* @throws Exception
*/
public List<Map<String, Object>> queryList(int dataSource) throws Exception;
}
查詢數據接口實現 DataSourceDaoImpl.java
package cn.itssh.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import cn.itssh.dataSource.DataSourceContextHolder;
/**
* @ClassName: DataSourceDaoImpl.java
* @Description: TODO
* @author: SM(sm0210@qq.com)
* @date: 2017年6月14日 下午5:49:04
*/
@Component
@Transactional
public class DataSourceDaoImpl extends SimpleJdbcDaoSupport implements DataSourceDao {
/**
* 多數據源
*/
@Override
public List<Map<String, Object>> queryList(int dataSource) throws Exception {
//
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
//
StringBuffer sb = new StringBuffer("select id,name from demo_table1");
//
ParameterizedRowMapper<Map<String, Object>> map = null;
//第二個數據源sql
if(dataSource == 2){
//清空內容
sb.setLength(0);
//
sb.append("select id,name from student");
}
//
//默認查詢第一個數據源
map = new ParameterizedRowMapper<Map<String, Object>>(){
//
public Map<String, Object> mapRow(ResultSet rs, int arg1) throws SQLException {
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", rs.getString("ID"));
params.put("name", rs.getString("NAME"));
//
return params;
}
};
//
list = this.getSimpleJdbcTemplate().query(sb.toString(), map);
//
return list;
}
}
測試方法:
/**
* 測試數據源
*/
public static void testDataSource(){
//設置數據源 1,2
int ds = 1;
//數據源
DataSourceContextHolder.setDataSource("dataSource" + ds);
//
DataSourceDao dataSourceDao = (DataSourceDao)ServiceHelper.getBean("dataSourceDaoImpl");
try {
//
List<Map<String, Object>> list = dataSourceDao.queryList(ds);
//
System.out.println("總記錄數:"+list.size() + "條,查詢到的數據為:");
//
System.out.println(list);
} catch (Exception e) {
System.out.println("查詢失敗...." + e.getMessage());
}finally{
//清空線程
DataSourceContextHolder.clearDataSource();
}
}