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

spring+springmvc+mybatis链接多数据源

2016-12-28 22:29 330 查看

1、创建枚举表示不同的数据源

/**
* 数据源的类别:ONE/TWO
*/
public enum DataSources {
ONE,TWO
}

2、通过 TheadLocal 来保存每个线程选择哪个数据源的标志(key):

package com.lcl.util;

import com.lcl.entity.DataSources;

public class DataSourceTypeManager {
private static final ThreadLocal<DataSources> dataSourceTypes = new ThreadLocal<DataSources>();

public static DataSources get(){
return dataSourceTypes.get();
}

public static void set(DataSources dataSourceType){
dataSourceTypes.set(dataSourceType);
}
//这里充值成xml配置文件中默认的数据源
public static void reset(){
dataSourceTypes.set(DataSources.ONE);
}
public static void clear() {
dataSourceTypes.remove();
}

}


3、定义 ThreadLocalRountingDataSource,继承AbstractRoutingDataSource:

package com.lcl.util;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceTypeManager.get();
}
}


4、创建db.properties文件存储数据源配置信息(这里偷个懒,本机上相同数据库不同的两个数据源)

urlOne:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
urlTwo:jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
driverClassName:com.mysql.jdbc.Driveruser
name:root
password:root


5、在ApplicationContext.xml配置文件中向 ThreadLocalRountingDataSource 注入 ONE和 TWO 等数据源:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd ">
<!-- 启用注解 -->
<context:annotation-config />

<!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描 -->
<context:component-scan base-package="com.lcl">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/classes/db.properties</value>  <!--这里可以配置多个源-->
</list>
</property>
</bean>
<!-- 配置数据源 -->
<bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="${urlOne}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="driverClassName" value="${driverClassName}" />
</bean>

<bean id="dataSourceTwo" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="${urlTwo}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="driverClassName" value="${driverClassName}" />
</bean>

<bean id="dataSource" class="com.lcl.util.ThreadLocalRountingDataSource">

<!--默认使用dataSourceOne作为数据源 -->

<property name="defaultTargetDataSource" ref="dataSourceOne" /> <property name="targetDataSources"> <map key-type="com.lcl.entity.DataSources"> <entry key="ONE" value-ref="dataSourceOne"/> <entry key="TWO" value-ref="dataSourceTwo"/> <!--这里的key值必须为枚举中的值,还可以加多个dataSource --> </map> </property> </bean>

<bean na
4000
me="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>

<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception"/>
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="edit*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>

<!-- 事物处理 -->
<aop:config>
<aop:pointcut id="pc" expression="execution(* com.fh.service..*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
</aop:config>

<!-- 配置mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<!-- mapper扫描 -->
<property name="mapperLocations" value="classpath:mybatis/*/*.xml"></property>
</bean>

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
<!--启动切面扫描-->

<aop:aspectj-autoproxy proxy-target-class="true"/></beans>


6、创建ApplicationContext-mvc.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>

<context:component-scan base-package="com.lcl.controller" />

<!-- 对静态资源文件的访问  restful-->
<mvc:resources mapping="/uploadFiles/**" location="/,/uploadFiles/" />

<!-- 访问拦截  -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/**"/>
<bean class="com.lcl.interceptor.LoginHandlerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

<!-- 配置SpringMVC的视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

<bean id="exceptionResolver" class="com.lcl.resolver.MyExceptionResolver"></bean>
<!-- 上传拦截,如最大上传值及最小上传值 -->
<bean id="multipartResolver"   class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="maxInMemorySize">
<value>4096</value>
</property>
<property name="defaultEncoding">
<value>utf-8</value>
</property>
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>


7、创建mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<settings>
<setting name="cacheEnabled" value="true" /><!-- 全局映射器启用缓存 -->
</settings>

<typeAliases>
<typeAlias type="com.lcl.entity.User" alias="User"/>
</typeAliases>

</configuration>


8、切面更换数据源(这个暂时不需要看了,不能对dao层进行切面,要切也只能对controller切面,应为在service中有事物,在一个事物中不能切换数据源,还没有找到解决方法,我现在是在controller中执行不同数据的代码是上面切换数据,执行完之后切换回来,应为在切面controller的话整个controller都只能操作一个数据源了)

//执行其他操作
DataSourceContextHolder.setDbType(DataSources.MALL);
userService.findValueByKey(map);
DataSourceContextHolder.setDbType(DataSources.MALL);
//继续执行其他操作

(下面这配置暂时不需要看了)

package com.lcl.systemManage;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
* 对dao层进行监控)
* @author Administrator
*
*/
@Component
@Aspect
public class DataSourcesChange {
/**
* 执行dao层方法前切换数据源
* @param point
* @throws Throwable
*/
@Before("execution(* com.lcl.dao..*(..))")
public void enterController(JoinPoint point) throws Throwable {

String methodName = point.getSignature().getName();//获取dao层执行的方法名

if(className.endwith("forTwo")){

DataSourceTypeManager.set(DataSources.Two);//如果执行的方法包含特定结尾,更换数据源

}
//这里根据方法名结尾有多个else if判断切换那个数据源

}

/** * dao执行完毕后切换回数据源 * @param point * @param result */
@AfterReturning(pointcut = "execution(* com.lcl.dao..*(..))",returning = "result")
public void logAfterExecution(JoinPoint point, Object result){
String methodName = point.getSignature().getName();//获取dao层执行的方法名
if(className.endwith("forTwo")){
DataSourceTypeManager.reset();//执行完成特定方法后切换回默认数据源
}
}
}


本文参考:http://blog.csdn.net/q908555281/article/details/50316137

           http://www.2cto.com/kf/201505/400273.html
      事物配置查看大神才知道:
http://blog.csdn.net/wangpeng047/article/details/43450189
   感谢大神资料参考,这里记下来以备后用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring mvc 多数据源