使用Aop和AbstractRoutingDataSource实现多数据源的配置
Spring多数据源的配置和使用
- <</span>bean
id="dataSourceFrom" class="com.mchange.v2.c3p0.ComboPooledDataSource"> -
<</span>property name="driverClass" value="${jdbc.driver}" /> -
<</span>property name="jdbcUrl" value="${jdbc.from.url}" /> -
<</span>property name="user" value="${jdbc.from.username}" /> -
<</span>property name="password" value="${jdbc.from.password}" /> -
<</span>property name="autoCommitOnClose" value="true" /> -
<</span>property name="checkoutTimeout" value="${cpool.checkoutTimeout}" /> -
<</span>property name="initialPoolSize" value="${cpool.minPoolSize}" /> -
<</span>property name="minPoolSize" value="${cpool.minPoolSize}" /> -
<</span>property name="maxPoolSize" value="${cpool.maxPoolSize}" /> -
<</span>property name="maxIdleTime" value="${cpool.maxIdleTime}" /> -
<</span>property name="acquireIncrement" value="${cpool.acquireIncrement}" /> -
<</span>property name="maxIdleTimeExcessConnect ions" value="${cpool.maxIdleTimeExcessConnect ions}" /> - </</span>bean>
- <</span>bean
id="dataSourceTo" class="com.mchange.v2.c3p0.ComboPooledDataSource"> -
<</span>property name="driverClass" value="${jdbc.driver}" /> -
<</span>property name="jdbcUrl" value="${jdbc.to.url}" /> -
<</span>property name="user" value="${jdbc.to.username}" /> -
<</span>property name="password" value="${jdbc.to.password}" /> -
<</span>property name="autoCommitOnClose" value="true" /> -
<</span>property name="checkoutTimeout" value="${cpool.checkoutTimeout}" /> -
<</span>property name="initialPoolSize" value="${cpool.minPoolSize}" /> -
<</span>property name="minPoolSize" value="${cpool.minPoolSize}" /> -
<</span>property name="maxPoolSize" value="${cpool.maxPoolSize}" /> -
<</span>property name="maxIdleTime" value="${cpool.maxIdleTime}" /> -
<</span>property name="acquireIncrement" value="${cpool.acquireIncrement}" /> -
<</span>property name="maxIdleTimeExcessConnect ions" value="${cpool.maxIdleTimeExcessConnect ions}" /> - </</span>bean>
- <</span>bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfi gurer"> -
<</span>property name="locations" value="classpath:jdbc.properties" /> - </</span>bean>
- public
class DynamicDataSource extends AbstractRoutingDataSourc e{ -
-
@Override -
protected Object determineCurrentLookupKe y() { -
return DBContextHolder.getDBType(); -
} - }
- public
class DBContextHolder{ -
public static final String DATA_SOURCE_FROM = "dataSourceFrom"; -
public static final String DATA_SOURCE_TO = "dataSourceTo"; -
-
private static final ThreadLocal contextHolder = new ThreadLocal(); -
-
public static void setDBType(String dbType) { -
contextHolder.set(dbType); -
} -
-
public static String getDBType() { -
return contextHolder.get(); -
} -
-
public static void clearDBType() { -
contextHolder.remove(); -
} - }
- <</span>bean
id="dynamicDataSource" class="datasource.DynamicDataSource" > -
-
<</span>property name="targetDataSources"> -
<</span>map> -
<</span>entry value-ref="dataSourceFrom" key="dataSourceFrom"></</span>entry> -
<</span>entry value-ref="dataSourceTo" key="dataSourceTo"></</span>entry> -
</</span>map> -
</</span>property> -
<</span>property name="defaultTargetDataSource" ref="dataSourceFrom" /> - </</span>bean>
-
- <</span>bean
id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> -
<</span>property name="dataSource"> -
<</span>ref bean="dynamicDataSource" /> -
</</span>property> - </</span>bean>
-
-
- <</span>bean
id="sqlBaseDAO" class="com.whty.dao.BaseDAOImpl"> -
<</span>property name="jdbcTemplate"> -
<</span>ref bean="jdbcTemplate" /> -
</</span>property> - </</span>bean>
在ORM框架Hibernate中的使用配置示例:
- <</span>bean
id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactory Bean"> -
-
<</span>property name="dataSource" ref="dynamicDataSource" /> -
<</span>property name="configLocations" value="classpath:hibernate.cfg.xml" /> -
<</span>property name="hibernateProperties"> -
<</span>props> -
<</span>prop key="hibernate.dialect">${hibernate.dialect}</</span>prop> -
</</span>property> - </</span>bean>
使用动态数据源的时候,可以看出和使用单数据源的时候相比,在使用配置上几乎没有差别,在进行性事务管理配置的时候也没有差别:
使用Spring的JdbcTemplate的事务管理配置示例:
- <</span>bean
id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionMan ager"> -
<</span>property name="dataSource" ref="dynamicDataSource" /> - </</span>bean>
-
- <</span>bean
id="sqlBaseDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryB ean"> -
<</span>property name="transactionManager" ref="transactionManager" /> -
<</span>property name="target" ref="sqlBaseDAO" /> -
<</span>property name="transactionAttributes"> -
<</span>props> -
<</span>prop key="insert*">PROPAGATION_REQUIRED</</span>prop> -
<</span>prop key="*">PROPAGATION_REQUIRED,readOnly</</span>prop> -
</</span>props> -
</</span>property> - </</span>bean>
使用Hibernate时的事务管理配置示例:
- <</span>tx:annotation-driven
transaction-manager="transactionManager"/> -
- <</span>bean
id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionMana ger"> -
<</span>property name="sessionFactory" ref="sessionFactory" /> - </</span>bean>
如何选择控制每个业务中需要的具体数据源,可是使用手动控制:
- ApplicationContext
context = new ClassPathXmlApplicationC ontext("applicationContext.xml"); - BaseDAO
dao = (BaseDAO) context.getBean("sqlBaseDAO", BaseDAOImpl.class); -
- try
{ -
DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_FROM); -
System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM")); -
DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_TO); -
System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM")); -
- }
catch (Exception e) { -
e.printStackTrace(); - }
也可以采用AOP的控制方式:
- @Aspect
- public
class DynamicDataSourceAspect { -
@Pointcut("execution (public service.impl..*.*(..))") -
public void serviceExecution(){} -
-
@Before("serviceExecution()") -
public void setDynamicDataSource(JoinPoint jp) { -
for(Object o : jp.getArgs()) { -
//处理具体的逻辑 ,根据具体的境况CustomerContextHolder.setCustomerType()选取DataSource -
} -
} - }