来源: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();
}
}