基于spring来配置和使用多数据源还是比较简单的,因为spring框架已经预留了这样的接口可以方便数据源的切换。
DynamicDataSource类
package com.demo.core;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}
}
DynamicDataSourceHolder类
package com.demo.core;
public class DynamicDataSourceHolder {
/**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal THREAD_DATA_SOURCE = new ThreadLocal();
public static String getDataSource() {
return THREAD_DATA_SOURCE.get();
}
public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
}
public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
}
}
注解
package com.demo.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE,ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}
切面
package com.demo.core;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
public class DataSourceAspect {
/**
* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*
* @param point
* @throws Exception
*/
public void intercept(JoinPoint point) throws Exception {
Class> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}
/**
* 提取目标对象方法注解和类型注解中的数据源标识
*
* @param clazz
* @param method
*/
private void resolveDataSource(Class> clazz, Method method) {
try {
Class>[] types = method.getParameterTypes();
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
} catch (Exception e) {
System.out.println(clazz + ":" + e.getMessage());
}
}
}
service类
package com.demo.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.demo.core.DataSource;
import com.demo.core.DynamicDataSourceHolder;
import com.demo.dao.UserDAO;
import com.demo.model.User;
import com.demo.service.UserService;
@Service
public class UserServiceImpl implements UserService{
@Autowired
@Qualifier("userDAO")
private UserDAO userDAO;
public int insertUser(User user) {
return userDAO.insertUser(user);
}
public User queryUserById(String id) {
return userDAO.queryUserByID(id);
}
@DataSource("dataSource1")//通过元注解 利用切面运行时自动设置数据源
public User queryUserByIdDB2(String id) {
//DynamicDataSourceHolder.setDataSource("dataSource2");
//手动设置数据源
return userDAO.queryUserByID(id);
}
}
dao类
package com.demo.dao;
import org.springframework.stereotype.Repository;
import com.demo.model.User;
@Repository
public interface UserDAO {
public int insertUser(User user);
public User queryUserByID(String id);
}
单元测试service
package test.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.demo.service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/conf/spring-mybatis.xml"}) //加载配置文件
public class userServiceTest{
@Autowired
private UserService userservice;
@Test
public void testuserService(){
// System.err.println(userservice.queryUserById("1"));
System.err.println(userservice.queryUserByIdDB2("1"));
}
}
控制台输出
User [id=1, name=数据源2, password=admin2]
配置文件
转载 http://blog.csdn.net/wangpeng047/article/details/8866239/ spring多数据源配置
转载 http://download.csdn.net/download/npf_java/8786825 多数据源事务控制