因爲項目須要從已經運行的多個項目的數據庫中取值,因此就出現了須要訪問多個數據源的狀況。 java
Spring配置文件 mysql
<!-- 屬性文件讀入 --> <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; }