Spring JDBC 多数据源管理

原创
2012/11/02 12:37
阅读数 1.6K

由于项目需要从已经运行的多个项目的数据库中取值,所以就出现了需要访问多个数据源的情况。

Spring配置文件

<!-- 属性文件读入 -->
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath*:resources/spring/database.properties</value>
			</list>
		</property>
	</bean>

	<bean id="jdbcTemplate"
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg ref="dynamicDataSource" />
	</bean>

	<bean id="dynamicDataSource" class="com.primemis.datasource.DynamicDataSource">
		<!-- 通过key-value的形式来关联数据源 -->
		<property name="targetDataSources">
			<map key-type="com.primemis.datasource.DatabaseType">
				<entry key="DEFAULT" value-ref="defaultDataSource"></entry>
				<entry key="COUNTER" value-ref="counterDataSource"></entry>
				<entry key="XPOS" value-ref="xposDataSource"></entry>
				<entry key="CONXPOS" value-ref="conxposDataSource"></entry>
				<entry key="ESPOS" value-ref="esposDataSource"></entry>
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="defaultDataSource">
		</property>
	</bean>


	<!--MySql 数据源配置 Bgn -->
	<bean id="defaultDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${mysql.driverclass}"></property>
		<property name="jdbcUrl" value="${mysql.jdbcurl}"></property>
		<property name="user" value="${mysql.user}"></property>
		<property name="password" value="${mysql.password}"></property>
		<property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"></property>
		<property name="acquireIncrement" value="${jdbc.acquireIncrement}"></property>  <!-- 当连接池中的连接用完时,C3P0一次性创建新连接的数目2 -->
		<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>  <!-- 初始化时创建的连接数,必须在minPoolSize和maxPoolSize之间 -->
		<property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
		<!-- 最大空闲时间,超过空闲时间的连接将被丢弃 [需要注意:mysql默认的连接时长为8小时(28800)【可在my.ini中添加 wait_timeout=30(单位秒)设置连接超时】,这里设置c3p0的超时必须<28800] -->
		<property name="maxIdleTime" value="${jdbc.maxIdleTime}"></property>
		<!-- <property name="idleConnectionTestPeriod" value="60"></property> --> <!-- 每60秒检查连接池中的空闲连接 -->
		<!-- <property name="maxStatements" value="20"></property> -->  <!-- jdbc的标准参数 用以控制数据源内加载的PreparedStatement数量,但由于预缓存的Statement属 于单个Connection而不是整个连接 -->
	</bean>
	<!--MySql 数据源配置 End -->

	<!--客流系统 Sql Server 数据源配置 Bgn -->
	<bean id="counterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${counter.driverclass}"></property>
		<property name="jdbcUrl" value="${counter.jdbcurl}"></property>
		<property name="user" value="${counter.user}"></property>
		<property name="password" value="${counter.password}"></property>
		<property name="checkoutTimeout" value="${jdbc.checkoutTimeout}"></property>
		<property name="acquireIncrement" value="${jdbc.acquireIncrement}"></property>  <!-- 当连接池中的连接用完时,C3P0一次性创建新连接的数目2 -->
		<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>  <!-- 初始化时创建的连接数,必须在minPoolSize和maxPoolSize之间 -->
		<property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
		<!-- 最大空闲时间,超过空闲时间的连接将被丢弃 [需要注意:mysql默认的连接时长为8小时(28800)【可在my.ini中添加 wait_timeout=30(单位秒)设置连接超时】,这里设置c3p0的超时必须<28800] -->
		<property name="maxIdleTime" value="${jdbc.maxIdleTime}"></property>
		<!-- <property name="idleConnectionTestPeriod" value="60"></property> --> <!-- 每60秒检查连接池中的空闲连接 -->
		<!-- <property name="maxStatements" value="20"></property> -->  <!-- jdbc的标准参数 用以控制数据源内加载的PreparedStatement数量,但由于预缓存的Statement属 于单个Connection而不是整个连接 -->
	</bean>

	<!--客流系统 Sql Server 数据源配置 End -->

	<!-- Sybase JDBC信息配置 Bgn -->
	<bean id="aDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${Sybase.driverClassName}">
		</property>
		<property name="jdbcUrl" value="${a.url}"></property>
		<property name="user" value="${a.userName}"></property>
		<property name="password" value="${a.password}"></property>
	</bean>
	<bean id="bDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${Sybase.driverClassName}">
		</property>
		<property name="jdbcUrl" value="${b.url}"></property>
		<property name="user" value="${b.userName}"></property>
		<property name="password" value="${b.password}"></property>
	</bean>
	<bean id="cDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${Sybase.driverClassName}">
		</property>
		<property name="jdbcUrl" value="${c.url}"></property>
		<property name="user" value="${c.userName}"></property>
		<property name="password" value="${c.password}"></property>
	</bean>
	<!-- Sybase JDBC信息配置 End -->
DynamicDataSource类

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

public class DynamicDataSource extends AbstractRoutingDataSource {

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

}
DatabaseContextHolder类

import org.springframework.util.Assert;

public class DatabaseContextHolder {

	private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<DatabaseType>();

	public static void setDatabaseType(DatabaseType DatabaseType) {
		Assert.notNull(DatabaseType, "DatabaseType cannot be null");
		contextHolder.set(DatabaseType);
	}

	public static DatabaseType getDatabaseType() {
		return (DatabaseType) contextHolder.get();
	}

	public static void clearDatabaseType() {
		contextHolder.remove();
	}
}
Dao使用方式

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
	public int update(String sql, SqlParameterSource paramSource,
			DatabaseType type) {
		DatabaseContextHolder.setDatabaseType(type);
		int rows = this.jdbc.update(sql, paramSource);
		DatabaseContextHolder.clearDatabaseType();
		return rows;
	}

展开阅读全文
打赏
0
18 收藏
分享
加载中
这个我喜欢。。
2013/01/10 12:59
回复
举报
更多评论
打赏
1 评论
18 收藏
0
分享
在线直播报名
返回顶部
顶部