Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法(二)

2014-11-24 09:04:18 · 作者: · 浏览: 1
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
}
}
CustomerContextHolder
package com.hoo.framework.spring.support;
/**
* function: 多数据源
* @author hoojo
* @createDate 2013-9-27 上午11:36:57
* @file CustomerContextHolder.java
* @package com.hoo.framework.spring.support
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public abstract class CustomerContextHolder {
public final static String DATA_SOURCE_ORACLE = "oracleDataSource";
public final static String DATA_SOURCE_MYSQL = "mySqlDataSource";
private static final ThreadLocal contextHolder = new ThreadLocal();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
}
public static String getCustomerType() {
return contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
其中,常量对应的applicationContext-datasource.xml中的multipleDataSource中的targetDataSource的key,这个很关键不要搞错了。
3、测试看能否切换数据源
package com.hoo.framework.service.impl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hoo.framework.dao.BaseDao;
import com.hoo.framework.log.ApplicationLogging;
import com.hoo.framework.spring.support.CustomerContextHolder;
/**
* function:多数据源测试服务接口测试
* @author hoojo
* @createDate 2013-10-10 上午11:18:18
* @file MultipleDataSourceServiceImplTest.java
* @package com.hoo.framework.service.impl
* @project SHMB
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
@ContextConfiguration({ "classpath:applicationContext-datasource.xml", "classpath:applicationContext-base.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class MultipleDataSourceServiceImplTest extends ApplicationLogging {
@Autowired
private BaseDao dao;
@Test
public void testDao() {
info(dao.toString());
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
info(dao.findBySql("select * from devicestate_tab where rownum < 2").toString());
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
info(dao.findBySql("select * from city limit 2").toString());
}
}
运行上面的测试用例后可以发现能查询到数据,如果我们注释掉其中的一项setCustomerType就会出现查询错误。在其中一个
数据库
没有找到对应的table。
至此,切换数据源也算成功了大半,剩下的就是如何在实际的业务中完成数据源的“动态”切换呢?!难道还是要像上面一样在每个方法上面写一个setCustomerType来手动控制数据源!答案是“当然不是”。我们用过Spring、hibernate后就会知道,先去使用hibernate的时候没有用spring,事务都是手动控制的。自从用了Spring大家都轻松了很多,事务交给了Spring来完成。所以到了这里你大概知道怎么做了,如果你还不知道~嘿嘿……(Spring那你就懂了个皮毛,最经典的部分你没有学到)
所以就是利用Spring的Aop进行切面 编程,拦截器Interceptor在这里是一个很好的选择。它可以在方法之前或方法之后完成一些操作,而且控制的粒度可以细到具体的方法中的参数、返回值、方法名等。在这里控制数据源动态切换最好不过了!
4、上面是手动切换数据源,我们用Spring的Aop拦截器整个更自动化的方法来切换数据源。
Spring配置文件 applicationContext-base.xml
< xml version="1.0" encoding="UTF-8" >
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">