springMvc +hibernate 实现多数据源动态切换
一、实现目的最近在做任务统计平台,对平台大体做一个介绍。两个平台,学科学习资源管理平台和学科教学资源管理平台,每个平台下有三科(外数语),另外加统一认证平台,七个项目也就是说有7个数据源。
虽然说是两个平台,但只是业务逻辑稍微不同罢了,各个科目下的dao和service以及JOB其实都是可以统用的。以前各个定时统计任务都是分布在各个科目中的,导致一开始做的时候就要拷贝多份,特别是业务逻辑修改的时候特别头疼,各种拷贝,还得写一堆上线单。
所以采用springMvc+hibernate+mysql+dubbo 实现的多数据源切换 统计平台,实现对dao和
service以及job层的统一调用,只需切换不同的数据源即可。dubbo这里只是做远程接口调用,暂且可以不用看。
二、实现方式
1、配置 applicationContext-datasource.xml
这里是简单的配置了2个数据源做实例,统一配置和学科学习数学科目的数据源。 <!-- 统一配置数据源 -->
<bean id="dataSourceSSO" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url_SSO}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<!-- 配置数学数据源 -->
<bean id="dataSourceFmM" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url_Fm_M}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.pass}" />
</bean>
<bean id="multipleDataSource" class="com.acts.web.common.persistence.DynamicDataSource">
<property name="defaultTargetDataSource" ref="dataSourceFmM"/>
<property name="targetDataSources">
<map>
<!-- 注意这里的value是和上面的DataSource的id对应,key要和下面的CustomerContextHolder中的常量对应 -->
<entry value-ref="dataSourceSSO"key="SSODataSource"/>
<entry value-ref="dataSourceFmM"key="MDataSourceFm"/>
</map>
</property>
</bean>
<!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="multipleDataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<!-- 链接释放策略 on_close | after_transaction | after_statement | auto-->
<prop key="hibernate.connection.release_mode">after_transaction</prop>
<!--<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop> -->
<!--数据库批量查询最大数 -->
<prop key="hibernate.jdbc.fetch_size">50</prop>
<!--数据库批量更新、添加、删除操作最大数 -->
<prop key="hibernate.jdbc.batch_size">50</prop>
</props>
</property>
</bean>
<!-- 统一配置AOP切面注入 直接切入dao层使用默认数据源-->
<aop:config>
<aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor">
<aop:pointcut id="daoSSO" expression="within(com.acts.web.modules.rmp.dao.AnalysisQuesSsoDao)" />
<aop:before pointcut-ref="daoSSO" method="setdataSourceSSO" />
</aop:aspect>
</aop:config>
2、applicationContext.xml 数据库参数配置
<!-- 加載配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:persistence-mysql.properties</value>
</list>
</property>
</bean>
3、DatabaseContextHolder.java 多数据源
/**
* 多数据源
* 创建者 张志朋
* 创建时间 2016年5月26日
*
*/
public class DatabaseContextHolder {
public final static String DATA_SOURCE_SSO = "SSODataSource";
public final static String DATA_SOURCE_FM_MATH = "MDataSourceFm";
public final static String DATA_SOURCE_FM_ENGLISH = "EDataSourceFm";
public final static String DATA_SOURCE_FM_CHINESE = "LDataSourceFm";
public final static String DATA_SOURCE_K12_MATH = "MDataSourceK12";
public final static String DATA_SOURCE_K12_ENGLISH = "EDataSourceK12";
public final static String DATA_SOURCE_K12_CHINESE = "LDataSourceK12";
public final static String DATA_SOURCE_K12 = "K12DataSource";
public final static String DATA_SOURCE_K12_ONLINE = "K12OnlineDataSource";
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
4、DynamicDataSource.java动态据源实现
/**
* 动态据源实现
* 创建者 张志朋
* 创建时间 2016年5月25日
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseContextHolder.getCustomerType();
}
}5、DataSourceInterceptor.java 拦截器实现 注入
/**
* 拦截器实现 注入
* 创建者 张志朋
* 创建时间 2016年5月26日
*
*/
@Component
public class DataSourceInterceptor {
public void setdataSourceSSO(JoinPoint jp) {
DatabaseContextHolder.setCustomerType("SSODataSource");
}
}
6、MultipleDataSourceServiceImplTest.java单元测试
@ContextConfiguration({ "classpath:applicationContext-datasource.xml",
"classpath:applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class MultipleDataSourceServiceImplTest {
@Test
public void testDao() {
//数学科目 统计
DatabaseContextHolder.setCustomerType(DatabaseContextHolder.DATA_SOURCE_FM_MATH);
//英语科目 统计
DatabaseContextHolder.setCustomerType(DatabaseContextHolder.DATA_SOURCE_FM_ENGLISH);
//语文科目 统计
DatabaseContextHolder.setCustomerType(DatabaseContextHolder.DATA_SOURCE_FM_CHINESE);
}
}
运行单元测试,三科的统计 通过使用各自的数据源调用相同的JOB和service以及dao层实现任务统计。
如果 有不明白的地方 可以加群 或者我的QQ 获得帮助{:2_27:}
页:
[1]