1.在applicationContext.xml中配置好多数据源
<!--引入数据库配置文件-->
<context:property-placeholder location="classpath:dbconfig.properties"/>
<!--引入数据库配置文件-->
<context:property-placeholder location="classpath:test.properties"/>
<!--导入applicationContext-mvc配置-->
<import resource="applicationContext-mvc.xml"/>
<!--配置druid输出日志-->
<bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
<property name="resultSetLogEnabled" value="false" />
</bean>
<!--=========================================================================================================================================-->
<!--使用druid连接池配置数据源-->
<bean id="dataSource1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--配置数据库连接-->
<property name="driverClassName" value="${dbconfig1.driverClassName}" />
<property name="url" value="${dbconfig1.url}" />
<property name="username" value="${dbconfig1.username}" />
<property name="password" value="${dbconfig1.password}" />
<!--配置连接池大小-->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="30" />
<!--配置最大等待连接时间-->
<property name="maxWait" value="60000" />
<!--配置多长时间检查一次,检查需要关闭空闲连接,单位为毫秒-->
<property name="timeBetweenEvictionRunsMillis" value="6000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="180" />
<!--关闭abanded连接时输出错误日志-->
<property name="logAbandoned" value="true" />
<!--配置一个连接在连接池中最小的生存时间-->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!--配置一个校验检验连接是否可用,value是一个sql语句用来校验的-->
<property name="validationQuery" value="SELECT * FROM goods" />
<!--配置测试,和上面的validationQuery组合起来使用-->
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!--配置PSCache,mysql使用这个提升不大,所以建议不使用-->
<property name="poolPreparedStatements" value="false" />
<!--配置日志输出路径-->
<property name="proxyFilters">
<list>
<ref bean="log-filter" />
</list>
</property>
</bean>
<!--使用druid连接池配置数据源-->
<bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--配置数据库连接-->
<property name="driverClassName" value="${dbconfig2.driverClassName}" />
<property name="url" value="${dbconfig2.url}" />
<property name="username" value="${dbconfig2.username}" />
<property name="password" value="${dbconfig2.password}" />
<!--配置连接池大小-->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="30" />
<!--配置最大等待连接时间-->
<property name="maxWait" value="60000" />
<!--配置多长时间检查一次,检查需要关闭空闲连接,单位为毫秒-->
<property name="timeBetweenEvictionRunsMillis" value="6000" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="180" />
<!--关闭abanded连接时输出错误日志-->
<property name="logAbandoned" value="true" />
<!--配置一个连接在连接池中最小的生存时间-->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!--配置一个校验检验连接是否可用,value是一个sql语句用来校验的-->
<property name="validationQuery" value="SELECT * FROM goods" />
<!--配置测试,和上面的validationQuery组合起来使用-->
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!--配置PSCache,mysql使用这个提升不大,所以建议不使用-->
<property name="poolPreparedStatements" value="false" />
<!--配置日志输出路径-->
<property name="proxyFilters">
<list>
<ref bean="log-filter" />
</list>
</property>
</bean>
2.在applicationContext.xml中配置druid的各项参数
<!--配置druid的sql注入检测-->
<bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">
<!--对被认为是攻击的SQL进行LOG.error输出-->
<property name="logViolation" value="true" />
<!--对被认为是攻击的SQL抛出SQLExcepton-->
<property name="throwException" value="false" />
</bean>
<!--配置druid的连接池状态的监控-->
<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<!-- 监控sql执行大于3s的sql -->
<property name="slowSqlMillis" value="3000" />
<property name="logSlowSql" value="true" />
<property name="mergeSql" value="true" />
</bean>
3.在applicationContext.xml中配置动态数据源
<!--配置动态数据源-->
<bean id="dynamicDataSource" class="com.zengjx.config.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1" />
<entry value-ref="dataSource2" key="dataSource2" />
</map>
</property>
<!--配置默认使用的数据源-->
<property name="defaultTargetDataSource" ref="dataSource1"></property>
</bean>
<!--配置sqlsessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--配置连接的数据源-->
<property name="dataSource" ref="dynamicDataSource" />
<!--配置*Mapper.xml文件路径-->
<property name="mapperLocations" value="classpath*:com.zengjx.mapper/*Mapper.xml" />
<!--配置mybatis类型别名,返回数据封装的类就可以直接写类名不用再写全路径名-->
<property name="typeAliasesPackage">
<value>
com.zengjx.domain
</value>
</property>
</bean>
<!--配置mapper映射-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zengjx.mapper" />
</bean>
4.在applicationContext.xml中配置好事务
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--配置数据源-->
<property name="dataSource" ref="dynamicDataSource" />
</bean>
<!--配置事务-->
<tx:advice id="txAdvice">
<tx:attributes>
<!--如果是查询的方式配置为只读状态的事务,提高效率-->
<tx:method name="get*" read-only="true" propagation="SUPPORTS" rollback-for="Exception" />
<tx:method name="find*" read-only="true" propagation="SUPPORTS" rollback-for="Exception"/>
<tx:method name="query*" read-only="true" propagation="SUPPORTS" rollback-for="Exception"/>
<tx:method name="select*" read-only="true" propagation="SUPPORTS" rollback-for="Exception"/>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!--配置切面-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.zengjx.service.*.*(..))" />
</aop:config>
5.在applicationContext.xml中其余配置
<!-- 启用MVC注解 -->
<mvc:annotation-driven/>
<!--开启扫描-->
<context:component-scan base-package="com.zengjx" />
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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启静态资源放行-->
<mvc:default-servlet-handler />
<!--开启springmvc注解支持,可使用@RequestMapping注解-->
<mvc:annotation-driven />
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀:返回jsp前面的文件路径 -->
<property name="prefix" value="/WEB-INF/views/" />
<!-- 后台缀:返回jsp后缀名 -->
<property name="suffix" value=".jsp" />
</bean>
<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1MB -->
<property name="maxUploadSize">
<value>104857600</value>
</property>
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
</beans>
7.继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法
package com.zengjx.config;
import com.zengjx.utils.DataSourceContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
//获取到数据源
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDbType();
}
}
8.切换数据源的一个工具类
package com.zengjx.utils;
public class DataSourceContextHolder {
//配置数据源常量
public static final String DATA_SOURCE_1 = "dataSource1";
public static final String DATA_SOURCE_2 = "dataSource2";
//将当前线程绑定数据源
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
public static String getDbType() {
return ((String) contextHolder.get());
}
public static void clearDbType() {
contextHolder.remove();
}
}