Spring MVC +MyBatis 多数据源配置

本文详细介绍了如何在Spring MVC项目中结合MyBatis实现多数据源配置,从配置文件到Java代码,再到Service层的直接调用,全面解析整个配置过程。
摘要由CSDN通过智能技术生成


配置文件


	<!-- 1. 数据源 : DriverManagerDataSource -->
	<context:property-placeholder location="classpath:config/jdbc.properties" />
	
	<!-- 数据源1 org.apache.commons.dbcp.BasicDataSource com.alibaba.druid.pool.DruidDataSource -->
    <bean id="tDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    
       	<property name="driverClassName">
			<value>${jdbc.t.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.t.url}</value>
		</property>
		<property name="username">
			<value>${jdbc.t.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.t.password}</value>
		</property>


        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0" />
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000" />


        <property name="validationQuery"><value>SELECT 1</value></property> 
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="testWhileIdle" value="true" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="25200000" />

        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="true" />
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="1800" />
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="true" />

        <!-- 监控数据库 -->
        <!-- <property name="filters" value="stat" /> -->
        <property name="filters" value="mergeStat" />
    </bean>
	
	<bean id="sDataSource" class="com.alibaba.druid.pool.DruidDataSource">
    
       	<property name="driverClassName">
			<value>${jdbc.s.driverClassName}</value>
		</property>
		<property name="url">
			<value>${jdbc.s.url}</value>
		</property>
		<property name="username">
			<value>${jdbc.s.username}</value>
		</property>
		<property name="password">
			<value>${jdbc.s.password}</value>
		</property>


        <!-- 初始化连接大小 -->
        <property name="initialSize" value="0" />
        <!-- 连接池最大使用连接数量 -->
        <property name="maxActive" value="20" />
        <!-- 连接池最小空闲 -->
        <property name="minIdle" value="0" />
        <!-- 获取连接最大等待时间 -->
        <property name="maxWait" value="60000" />


        <property name="validationQuery"><value>SELECT 1</value></property> 
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="testWhileIdle" value="true" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="25200000" />

        <!-- 打开removeAbandoned功能 -->
        <property name="removeAbandoned" value="true" />
        <!-- 1800秒,也就是30分钟 -->
        <property name="removeAbandonedTimeout" value="1800" />
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="true" />

        <!-- 监控数据库 -->
        <!-- <property name="filters" value="stat" /> -->
        <property name="filters" value="mergeStat" />
    </bean>
    
	<!--多数据源配置 与 DynamicDataSource 对应-->
    <bean id="dataSource" class="com.whb.utils.db.DynamicDataSource">
        <property name="defaultTargetDataSource" ref="tDataSource"/>
        <property name="targetDataSources">
            <map>
                <entry key="tDataSource" value-ref="tDataSource"/>
                <entry key="sDataSource" value-ref="sDataSource"/>
            </map>
        </property>
    </bean>
    
    <bean id="dataSourceExchange" class="com.whb.utils.db.DataSourceExchange"/>
    
    <!-- 配置druid监控spring jdbc -->
    <bean id="druid-stat-interceptor"
        class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor">
    </bean>
    <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"
        scope="prototype">
        <property name="patterns">
            <list>
                <value>com.whb.service.impl.*</value>
            </list>
        </property>
    </bean>
    <aop:config>
        <aop:advisor advice-ref="druid-stat-interceptor"
            pointcut-ref="druid-stat-pointcut" />
    </aop:config>

 	<!-- 扫描文件(自动将servicec层注入) -->
    <context:component-scan base-package="com.whb.service" />
	<bean id="exceptionResolver" class="com.whb.exception.CustomSimpleMappingExceptionResolver">
	  <property name="exceptionMappings"> 
     	<props> 
		  <prop key="com.whb.exception.SystemException">error/500</prop> 
          <prop key="com.whb.exception.BusinessException">error/errorpage</prop>
		  <prop key="java.lang.exception">error/500</prop>
       </props> 
   	 </property> 
	</bean>
	<!-- <bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
		<property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" 
		class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property 
		name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" 
		value="jdbc:mysql://192.168.1.101:3038/sumecom_wohaibao" /> <property name="username" 
		value="root" /> <property name="password" value="binyao02123202" /> </bean> -->
	<!-- 2. mybatis的SqlSession的工厂: SqlSessionFactoryBean dataSource:引用数据源 MyBatis定义数据源,同意加载配置 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="configLocation" value="classpath:config/mybatis-config.xml" />
		<property name="typeAliasesPackage" value="com.whb.model" />
	</bean>

	<!-- 3. mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory 
		basePackage:指定sql映射文件/接口所在的包(自动扫描) -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.whb.mapper"></property>
		<!-- 
		<property name="sqlSessionFactory" ref="sqlSessionFactory"></property> -->
	</bean>

	<!-- 对数据源进行事务管理 -->
	<!--
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
		p:dataSource-ref="dataSource" />  -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="remove*" propagation="REQUIRED" read-only="false"
				rollback-for="java.lang.Exception" />
			<tx:method name="delete*" propagation="REQUIRED" read-only="false"
				rollback-for="java.lang.Exception" />
			<tx:method name="add*" propagation="REQUIRED" read-only="false"
				/>
			<tx:method name="insert*" 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="update*" propagation="REQUIRED" read-only="false"
				rollback-for="java.lang.Exception" />
			<tx:method name="publish*" propagation="REQUIRED"
				read-only="false" rollback-for="java.lang.Exception" />
			<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="list*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="load*" propagation="SUPPORTS" read-only="true" />
			<tx:method name="validate*" propagation="SUPPORTS"
				read-only="true" />
		</tx:attributes>
	</tx:advice>
	<!--<aop:aspectj-autoproxy proxy-target-class="true"/>  -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<aop:config>
		<aop:pointcut id="pc"
			expression="execution(* com.whb.service.impl.*.*(..))" />
		<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" order="2" />
        <aop:advisor pointcut-ref="pc" advice-ref="dataSourceExchange" order="1" />  
	</aop:config>
	<!-- 日志拦截 -->
	<bean id="logAspect" class="com.whb.aspect.LogAspect"></bean>
	
	
	
	<!-- 多部分文件上传 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="10485760000" />
		<property name="maxInMemorySize" value="40960" />
		<property name="defaultEncoding" value="UTF-8"></property>
	</bean>
	<!-- 默认值如果适合,该项可以不用修改 -->
    <context:component-scan base-package="com.whb.task"/>
    <!-- 支持异步方法执行 -->
    <task:annotation-driven/>
</beans>


JAVA代码


import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
	String name() default DataSource.wohaibao;
	 
    public static String wohaibao = "tDataSource";
 
    public static String appointment = "sDataSource";
}

public class DataSourceContextHolder {  
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
    /** 
     * @Description: 设置数据源类型 
     * @param dataSource  数据源名称
     * @return void 
     * @throws 
     */  
    public static void setDataSource(String dataSource) {  
        contextHolder.set(dataSource);  
    }  
      
    /** 
     * @Description: 获取数据源名称 
     * @param  
     * @return String 
     * @throws 
     */  
    public static String getDataSource() {  
        return contextHolder.get();  
    }  
      
    /** 
     * @Description: 清除数据源名称
     * @param  
     * @return void 
     * @throws 
     */  
    public static void clearDataSource() {  
        contextHolder.remove();  
    }  
}  

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;


public class DataSourceExchange implements MethodBeforeAdvice,AfterReturningAdvice   
{  
  
    @Override  
    public void afterReturning(Object returnValue, Method method,  
            Object[] args, Object target) throws Throwable {  
        DataSourceContextHolder.clearDataSource();  
    }  
  
    @Override  
    public void before(Method method, Object[] args, Object target)  
            throws Throwable {  
      	//这里DataSource是自定义的注解,不是java里的DataSource接口
        if (method.isAnnotationPresent(DataSource.class))   
        {  
            DataSource datasource = method.getAnnotation(DataSource.class);
            if(null == datasource || (null != datasource && null == datasource.name()))
            	DataSourceContextHolder.setDataSource(datasource.wohaibao);
    		else {
    			System.out.println(datasource.name());
    			DataSourceContextHolder.setDataSource(datasource.name());  
    		}
        }  
//        else  
//        {  
//	    //target是被织入增强处理的目标对象,通过获取getDataSourceName函数来获取target的数据源名称
//            DataSourceContextHolder.setDataSource(
//			target.getClass.getMethod("getDataSourceName").invoke(target).toString());  
//        }  
          
    }
}  


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

public class DynamicDataSource extends AbstractRoutingDataSource {  
    @Override  
    protected Object determineCurrentLookupKey() {  
        return DataSourceContextHolder.getDataSource();  
    }  
}  



在 Service层 直接调用 

public interface sService {
	
	/**
	 * 调用多数据源
	 */
	@DataSource(name = DataSource.appointment)
	public sServiceRepView finds(sServiceReqView asrv);
	
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值