ssm dual data source mysql, sqlserver

History Help: project uses Spring + SpringMVC + Mybatis framework, have been using mysql database before the project, after the project docking required to configure multiple data sources to increase sqlserver database.
Comb related documents:
. 1, the pom.xml file (using the management tool maven)
2, the DataSource interfaces notation file
3, DataSourceAspect class file
4, DynamicDataSourceHolder class file
5, MultipleDataSource class files
6, jdbc.properties profile
7, spring-mybatis.xml configuration file
the above documents are indispensable! !
increased reliance jar file pom.xml

    <dependency>
        <groupId>net.sourceforge.jtds</groupId>
        <artifactId>jtds</artifactId>
        <version>1.2.4</version>
    </dependency>
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>sqljdbc4</artifactId>
        <version>2.0</version>
    </dependency>

jar package download: https://download.csdn.net/download/qq_35393472/10671922

DataSource interface annotation file

public class DynamicDataSourceHolder {
    /**
     * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
     */
    private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();

    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();
    }
}

MultipleDataSource class file
Note This file is a file called spring-mybatis.xml to give the required

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

/**
 * 多数据源使用
 * @author:lujingyu
 * @data:2018年9月15日下午2:33:40
 */
public class MultipleDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        // 从自定义的位置获取数据源标识
        return DynamicDataSourceHolder.getDataSource();
    }
}

jdbc.properties configuration files
File Description: mainly depends on the configuration of the two data sources should be very simple, common configuration to use according to their needs, can take over all use, but if you want to modify, then spring-mybatis.xml configuration when will this modification

#mysql数据源  使用该数据库查询时候 请在ServiceImpl类中增加注解:@DataSource("dataSource")
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc\:mysql\://192.168.0.167\:3306/online_db
jdbc.username=root
jdbc.password=123456

#sqlserver数据源 使用该数据库查询时候 请在ServiceImpl类中增加注解:@DataSource("sqlServerDataSource")
jdbc.sqlserver.driver=net.sourceforge.jtds.jdbc.Driver
jdbc.sqlserver.url=jdbc:jtds:sqlserver://192.168.0.117:1433/test_db
jdbc.sqlserver.username=lujingyu
jdbc.sqlserver.password=123456

#通用配置
jdbc.initialSize=3 
jdbc.minIdle=2
jdbc.maxActive=60
jdbc.maxWait=60000
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=30000
jdbc.validationQuery=SELECT 'x'
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false
jdbc.poolPreparedStatements=true
jdbc.maxPoolPreparedStatementPerConnectionSize=20
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=120
jdbc.logAbandoned=false
jdbc.filters=stat

spring-mybatis.xml profiles
the most important document to come, that I use all the configuration of the code, I added the comment "important" place you need to configure to use! ! ! ! ! ! ! ! Those who are marked important place must be configured! ! According to other needs can be ignored, I believe I can do more data source configuration can all be read to understand these codes!

<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    <!-- 自动扫描(自动注入) -->
    <context:component-scan base-package="com.newcsp.*.service;com.newcsp.*.*.service" />
    <!-- 定时任务 -->
    <!-- <context:component-scan base-package="com.newcsp.common.timer"/> -->

    <bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
        <property name="resultSetLogEnabled" value="true" />
    </bean>
    <!-- 重要!!!配置数据源mysql的下面的property 根据你jdbc.properties文件去配 -->
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.initialSize}" />
        <property name="minIdle" value="${jdbc.minIdle}" />
        <property name="maxActive" value="${jdbc.maxActive}" />
        <property name="maxWait" value="${jdbc.maxWait}" />
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
        <property name="testOnReturn" value="${jdbc.testOnReturn}" />
        <property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
        <!-- <property name="logAbandoned" value="${jdbc.logAbandoned}" /> -->
        <property name="filters" value="${jdbc.filters}" />
        <!-- 关闭abanded连接时输出错误日志 -->
        <property name="logAbandoned" value="true" />
        <property name="proxyFilters">
            <list>
                <ref bean="log-filter" />
            </list>
        </property>

        <!-- 监控数据库 -->
        <!-- <property name="filters" value="stat" /> -->
        <!-- <property name="filters" value="mergeStat" /> -->
    </bean>
    <!--重要!!!! sqlserver数据源 可以用这个配置做参考 mysql的加了一些功能配置 -->
    <bean id="sqlServerDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.sqlserver.driver}"/>
        <property name="url" value="${jdbc.sqlserver.url}"/>
        <property name="username" value="${jdbc.sqlserver.username}"/>
        <property name="password" value="${jdbc.sqlserver.password}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
        <property name="minIdle" value="${jdbc.minIdle}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
        <property name="maxWait" value="${jdbc.maxWait}"/>
        <property name="validationQuery" value="${jdbc.validationQuery}" />
        <property name="testWhileIdle" value="${jdbc.testWhileIdle}"/>
        <property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
        <property name="testOnReturn" value="${jdbc.testOnReturn}" />
        <property name="removeAbandoned" value="${jdbc.removeAbandoned}"/>
        <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}"/>
        <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
        <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}"/>
    </bean>

     <!-- 重要!!! 此处的class调用的就是上面的一个类文件 -->
    <bean id="multipleDataSource" class="com.newcsp.core.mybatis.MultipleDataSource">
        <!-- 指定默认的数据源 -->
        <property name="defaultTargetDataSource" ref="dataSource"/>

        <property name="targetDataSources">
            <map> <!-- 两个数据源的名称 -->
                <entry key="dataSource" value-ref="dataSource"/>
                <entry key="sqlServerDataSource" value-ref="sqlServerDataSource"/>
            </map>
        </property>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--单数据源使用 课忽略 -->
        <!-- <property name="dataSource" ref="dataSource" /> -->
        <!--重要!!!!多数据源使用  -->
        <property name="dataSource" ref="multipleDataSource"/>

        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="mapperLocations">
            <list>
                <value>classpath:com/newcsp/oracle/mapper/*.xml</value>
            </list>
        </property>
    </bean>

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>
    <bean id="baseMybatisDao" class="com.newcsp.core.mybatis.BaseMybatisDao">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.newcsp.oracle.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    <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="publish*" />
            <tx:method name="save*" />
            <tx:method name="add*" />
            <tx:method name="update*" />
            <tx:method name="insert*" />
            <tx:method name="create*" />
            <tx:method name="del*" />
            <tx:method name="load*" />
            <tx:method name="init*" />

            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- AOP配置 -->
    <aop:config>
        <aop:pointcut id="myPointcut"
            expression="execution(public * com.newcsp.*.service.impl.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
    </aop:config>

    <!--重要!!!!!此处用于拦截serverimpl层dataSource注解 用于多数据源使用  -->
    <bean id="dataSourceAspect" class="com.newcsp.core.mybatis.DataSourceAspect" />
        <aop:config>
                <aop:aspect ref="dataSourceAspect">
                <!-- 拦截所有service方法 -->
                    <aop:pointcut id="dataSourcePointcut"
                                    expression="execution(* com.newcsp.*.service.*.*(..))" />
                    <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
                </aop:aspect>
        </aop:config>
</beans>

Use Description:
Configure a method to intercept comment @DataSource in spring-mybatis.xml in
writing how to write the code to use is whether to go through serviceImpl achieve layer, add annotation layers to achieve
such as: @DataSource ( "dataSource" )
because in the allocation of spring-mybatis.xml my mysql configuration name called: dataSource
my sqlserver configuration name called sqlServerDataSource, which requires the use of a database to add this annotation database name on it!
E.g:

@Service
@DataSource("dataSource")
public class UserServiceImpl implements UserService {
}

This is the end, I do not understand can communicate. Welcome attention!
If I successfully help to you ~ ~ You can look at just charity -

Write pictures described here
---------------------
Author: Cold sarcastic expression
Source: CSDN
Original: https: //blog.csdn.net/qq_35393472/article/details/82744836
copyright notice : This article is a blogger original article, reproduced, please attach Bowen link!

===================================================================

Articles written by really good here, all copied, ha ha.

Talk about my problems, xml configuration interceptor did not work, I may be where configuration problem, I see there is that the priority of the problem, well, I do not know this one - learn

See: https://blog.csdn.net/qingrunhao/article/details/53102511

 <!--重要!!!!!此处用于拦截serverimpl层dataSource注解 用于多数据源使用  --> 
<bean id="dataSourceAspect" class="com.newcsp.core.mybatis.DataSourceAspect" />                       <aop:config> 
     <aop:aspect ref="dataSourceAspect"> 
        <!-- 拦截所有service方法 --> 
        <aop:pointcut id="dataSourcePointcut"
            expression="execution(* com.newcsp.*.service.*.*(..))" /> 
        <aop:before pointcut-ref="dataSourcePointcut" method="intercept" /> 
    </aop:aspect> 
</aop:config>

 amend as below:

Annotation-based configuration mode:

This part of the above comments, then added to the xml configuration file:

<context:component-scan base-package="com.policeCanteen.dataSource" />
<!-- 注解配置aop xml配置没起作用-->
<aop:aspectj-autoproxy />

 DataSourceAspect amended as follows:

package com.policeCanteen.dataSource;

import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class DataSourceAspect {
	
	
	@Pointcut("execution(* com.policeCanteen.service.*.*(..))")
	public void pointcut(){}
	/**
	 * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
	 * 
	 * @param point
	 * @throws Exception
	 */
	@Before(value="pointcut()")
	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());
		}
	}
}

This, my side on it. Give the original Bo Solo tours, hee hee:

Write pictures described here
---------------------
Author: Cold sarcastic expression
Source: CSDN
Original: https://blog.csdn.net/qq_35393472/article/details/82744836
copyright notice : This article is a blogger original article, reproduced, please attach Bowen link!

Published 39 original articles · won praise 6 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_40155654/article/details/88883987