配置两个数据源 + 一个 数据路由器
1 <!-- 数据源(主库) --> 2 <bean id="dataSource_main" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 3 <property name="jdbcUrl" value="${jdbc.url}"></property> 4 <property name="user" value="${jdbc.username}"></property> 5 <property name="password" value="${jdbc.password}"></property> 6 <property name="driverClass" value="${jdbc.driverClass}"></property> 7 8 <property name="maxPoolSize" value="${c3p0.pool.size.maxsize}"></property> 9 <property name="minPoolSize" value="${c3p0.pool.size.minsize}"></property> 10 <property name="initialPoolSize" value="${c3p0.pool.size.init}"></property> 11 <property name="acquireIncrement" value="${c3p0.pool.size.increment}"></property> 12 </bean> 13 14 <!-- 数据源(从库 继承主库) --> 15 <bean id="dataSource_1" parent="dataSource_main"> 16 <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/surveypark_1"></property> 17 </bean> 18 19 <!-- 数据路由器 --> 20 <bean id="datasource_router" class="kite.datasource.SurveyparkDataSourceRouter"> 21 <property name="targetDataSources"> 22 <map> 23 <entry key="odd" value-ref="dataSource_main" /> 24 <entry key="even" value-ref="dataSource_1"></entry> 25 </map> 26 </property> 27 <property name="defaultTargetDataSource" ref="dataSource_main"></property> 28 </bean> 29 30 <!-- 31 本地会话工厂bean,spring整合hibernate的核心入口 32 --> 33 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 34 <!-- 注入数据源 --> 35 <property name="dataSource" ref="datasource_router"></property> 36 <!-- 指定hibernate配置文件的位置 --> 37 <property name="configLocation" value="classpath:hibernate.cfg.xml"/> 38 <!-- 指定映射文件的位置 --> 39 <property name="mappingDirectoryLocations"> 40 <list> 41 <value>classpath:kite/domain</value> 42 </list> 43 </property> 44 </bean>
创建一个令牌类
1 package kite.datasource; 2 3 import kite.domain.Survey; 4 5 /** 6 * 调查令牌,绑定到当前的线程,传播到数据源路由器.进行分库判断 7 */ 8 public class SurveyToken 9 { 10 private Survey survey; 11 12 private static ThreadLocal<SurveyToken> t = new ThreadLocal<SurveyToken>(); 13 14 /** 15 * 将令牌对象绑定到当前线程 16 */ 17 public static void bindingToken(SurveyToken surveyToken) 18 { 19 t.set(surveyToken); 20 } 21 22 /** 23 * 从当前线程获得绑定的令牌对象 24 * @return 25 */ 26 public static SurveyToken getCurrentToken() 27 { 28 return t.get(); 29 } 30 31 /** 32 * 解除令牌的绑定 33 * @return 34 */ 35 public static void unbinToken() 36 { 37 t.remove(); 38 } 39 40 41 42 43 public Survey getSurvey() 44 { 45 return survey; 46 } 47 48 public void setSurvey(Survey survey) 49 { 50 this.survey = survey; 51 } 52 53 }
自定义数据源
1 package kite.datasource; 2 3 import java.sql.SQLFeatureNotSupportedException; 4 import java.util.logging.Logger; 5 6 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 7 8 /** 9 * 自定义数据源 10 */ 11 public class SurveyparkDataSourceRouter extends AbstractRoutingDataSource 12 { 13 14 protected Object determineCurrentLookupKey() 15 { 16 SurveyToken token = SurveyToken.getCurrentToken(); 17 18 if(token != null) 19 { 20 int id = token.getSurvey().getSurveyid(); 21 //解除绑定 22 SurveyToken.unbinToken(); 23 return (id % 2) == 0 ? "even":"odd"; 24 } 25 return null; 26 } 27 28 public Logger getParentLogger() throws SQLFeatureNotSupportedException 29 { 30 return null; 31 } 32 33 public <T> T unwrap() 34 { 35 return null; 36 } 37 38 public boolean isWrapperFor() 39 { 40 return false; 41 } 42 }
在action中进行绑定
//绑定到当前线程中
SurveyToken token = new SurveyToken();
token.setSurvey(getCurrentSurvey());
SurveyToken.bindingToken(token);