您的位置:首页 > 编程语言 > Java开发

Spring+SpringMVC+Mybatis 多数据源动态切换

2017-07-27 12:10 459 查看
首先配置数据源

<bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置连接池属性 -->
<property name="driverClass" value="${master.jdbc.driver}" />
<property name="jdbcUrl" value="${master.jdbc.url}" />
<property name="user" value="${master.jdbc.username}" />
<property name="password" value="${master.jdbc.password}" />
<!-- 配置连接池私有属性 [大部分小项目的使用连接池默认值就行了 大项目可以根据情况配置下列及其他属性 根据现场+实际经验+系统业务场景
来配置] -->
<!-- 最大连接数 -->
<property name="maxPoolSize" value="30" />
<!-- 最小连接数 -->
<property name="minPoolSize" value="10" />
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false" />
<!--获取连接超时时间 -->
<property name="checkoutTimeout" value="1000" />
<!-- 当获取连接失败后重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>

<bean id="slaveDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置连接池属性 -->
<property name="driverClass" value="${slave.jdbc.driver}" />
<property name="jdbcUrl" value="${slave.jdbc.url}" />
<property name="user" value="${slave.jdbc.username}" />
<property name="password" value="${slave.jdbc.password}" />
<!-- 配置连接池私有属性 [大部分小项目的使用连接池默认值就行了 大项目可以根据情况配置下列及其他属性 根据现场+实际经验+系统业务场景
来配置] -->
<!-- 最大连接数 -->
<property name="maxPoolSize" value="30" />
<!-- 最小连接数 -->
<property name="minPoolSize" value="10" />
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false" />
<!--获取连接超时时间 -->
<property name="checkoutTimeout" value="1000" />
<!-- 当获取连接失败后重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<bean id="dataSource" class="org.wq.ssm.db.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="master" value-ref="masterDataSource"/>
<entry key="slave" value-ref="slaveDataSource"/>
</map>
</property>
<!-- 默认数据源 -->
<property name="defaultTargetDataSource" ref="masterDataSource"/>
</bean>


注意:bean id=dataSource 这里的class被我们替换了

public class DynamicDataSource extends AbstractRoutingDataSource {

@Override
protected Object determineCurrentLookupKey() {
return DataSourceHolder.getDataSouce();
}

}

public class DataSourceHolder{
public static final ThreadLocal<String> holder = new ThreadLocal<String>();
public static void putDataSource(String name) {
holder.set(name);
}
public static String getDataSouce() {
System.out.println(holder.get());
return holder.get();
}
}


然后自定义一个注解

@Target({ ElementType.TYPE,ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface DataSourceAnnotatin {
String dataSource();
}


将注解使用在接口dao上面 dataSource里面的值为该dao对应的数据源的bean id

@DataSourceAnnotatin(dataSource="slave")
public interface UserInfoDao{}

@DataSourceAnnotatin(dataSource="master")
public interface LaswMenuDao{}


然后使用Aspect面向切面

public class DataSourceAspect {

private     Logger logger   =   LoggerFactory.getLogger(this.getClass());
@Pointcut("execution(* org.wq.ssm.dao..*.*(..))")
public void parentPcut() {
//System.out.println("暂时不做任何处理 方便下面的方法使用统一的execution 配置");
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Before("parentPcut()")
public void doBefore(JoinPoint joinPoint){
Object daoObj=joinPoint.getTarget();
Class[] interfacesClass = daoObj.getClass().getInterfaces();
for(Class cs:interfacesClass){
DataSourceAnnotatin dataSourceAnnotatin= (DataSourceAnnotatin) cs.getAnnotation(DataSourceAnnotatin.class);
if(dataSourceAnnotatin!=null){
DataSourceHolder.putDataSource(dataSourceAnnotatin.dataSource());
}
}
}

@After("parentPcut()")
public void doAfter(JoinPoint joinPoint) {
//DataSourceHolder.putDataSource(null);
}

}


注意需要将DataSourceAspect交由spring管理

<context:component-scan base-package="org.wq.ssm.aspect" />


测试

@Test
public void testQueryAll(){

List<UserInfo> userList=userInfoDao.queryAll();
for(UserInfo userInfo: userList){
System.out.println(userInfo);
}
System.out.println("-==========-");
List<LaswMenu> list=menuDao.queryAll();
for(LaswMenu ss: list){
System.out.println(ss);
}

}


测试结果

UserInfo [id=1, userName=xxxx, age=26, email=xxx@qq,com]

-==========-

org.wq.ssm.entity.lasw.LaswMenu@257cc1fc

org.wq.ssm.entity.lasw.LaswMenu@42e22a53

org.wq.ssm.entity.lasw.LaswMenu@57adfab0

org.wq.ssm.entity.lasw.LaswMenu@1949309d

……

OK 测试成功 !!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息