spring 配置两个数据源

本文介绍如何在一个系统中同时连接MySQL和SQLServer两个不同类型的数据库,包括配置数据源、编写Spring和MyBatis配置文件以及实现数据库切换的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景

       最近几天在忙集团演示的项目,现有的框架是 sql serveroraclemysql 均支持的,由于此项目用的是 mysql 数据库,而它还需要用到集团门禁系统的访客信息表和发卡系统的车辆信息表,而这两套系统用到的是 sql server 数据库。

        故需要在一个系统中连接两个不同的数据库(一个 mysql,一个 sql server, mysql 连接两个库),即配置两个数据源且连接 3 个数据库。

二、实现步骤

2.1 编写配置文件

        编写两个数据库配置文件,用于配置数据库用户名、密码等相关信息,由于使用的是 maven 工程,相关的目录结构如下

2.2 配置 mysql 的数据库

        1、先配置 mysql 的连接信息

        2、配置 sql server 的数据库相关信息,由于 sql server 连接了两个数据库,所以在一个配置文件里面配置了两个数据库名字和密码

2.3 编写配置文件

        编写两套 spring 配置文件,一套连接 mysql,一套连接 sql server

       首先编写 spring mysql 连接的配置文件 spring-mybatis.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:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.1.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
 http://cxf.apache.org/jaxws 
 http://cxf.apache.org/schemas/jaxws.xsd">
  <!-- 自动扫描 -->
  <context:component-scan base-package="com.zit">
        <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>classpath:mssql.properties</value>
			<value>classpath:mysql.properties</value>
		</list>
	</property>
	<property name="ignoreUnresolvablePlaceholders" value="false"></property>
  </bean>
  <!-- 配置数据库连接 -->
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"  destroy-method="close">
    <property name="driverClassName" value="${driver}" />
    <property name="url" value="${url}${dbName}${encoding}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${maxActive}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${maxWait}"></property>
    <!-- 解决长时间不连接,连接失败问题 -->
    <property name="testOnBorrow" value="${testOnBorrow}"></property>
    <property name="testOnReturn" value="${testOnReturn}"></property>
    <property name="testWhileIdle" value="${testWhileIdle}"></property>
    <property name="validationQuery" value="${validationQuery}"></property>
    
    <!-- 打开removeAbandoned功能 -->
    <property name="removeAbandoned" value="${removeAbandoned}" />
    <!-- 1800秒,也就是30分钟 -->
    <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
    <!-- 关闭abanded连接时输出错误日志 -->
    <property name="logAbandoned" value="${logAbandoned}" />

    <!-- 监控数据库 -->
    <property name="proxyFilters">
	    <list>
	        <ref bean="statfilter" />
	        <ref bean="logFilter" />
	    </list>
	</property>
    <property name="filters" value="${filters}" />
  </bean>
  <bean id="statfilter" class="com.alibaba.druid.filter.stat.StatFilter">
        <!-- 开启合并sql -->
        <property name="mergeSql" value="true" />
        <!-- 开启慢查询语句,1秒 -->
        <property name="slowSqlMillis" value="1000" />
        <property name="logSlowSql" value="true" />
    </bean>

    <bean id="logFilter" class="com.alibaba.druid.filter.logging.Log4jFilter">
        <!-- <property name="resultSetLogEnabled" value="false" /> -->
        <!-- <property name="statementExecutableSqlLogEnable" value="true" /> -->
    </bean>
 	<!-- 配置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.zit.cac.service.*</value>
            </list>
        </property>
    </bean>
    
   <aop:config>
   		<aop:pointcut id="cacpc" expression="execution(public * com.zit.cac.service.*.*(..))" />
   		<aop:advisor advice-ref="cacTxAdvice" pointcut-ref="cacpc" />
   		<aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" />
    </aop:config>
    
   <tx:advice id="cacTxAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		     <tx:method name="add*" propagation="REQUIRED" />
                     <tx:method name="append*" propagation="REQUIRED" />
                     <tx:method name="insert*" propagation="REQUIRED" />
                     <tx:method name="save*" propagation="REQUIRED" />
                     <tx:method name="update*" propagation="REQUIRED" />
                     <tx:method name="modify*" propagation="REQUIRED" />
                     <tx:method name="edit*" propagation="REQUIRED" />
                     <tx:method name="delete*" propagation="REQUIRED" />
                     <tx:method name="remove*" propagation="REQUIRED" />
                     <tx:method name="repair" propagation="REQUIRED" />
                     <tx:method name="delAndRepair" propagation="REQUIRED" />
                     <tx:method name="get*" propagation="REQUIRED" />
                     <tx:method name="datagrid*" propagation="REQUIRED" />
                     <tx:method name="query*" propagation="SUPPORTS" read-only="true" />
                     <tx:method name="select*" 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="search*" propagation="SUPPORTS" read-only="true" />
	             <tx:method name="count*" propagation="SUPPORTS" read-only="true" />
	             <tx:method name="truncate*" propagation="SUPPORTS" read-only="true" />
	             <tx:method name="menu*" propagation="SUPPORTS" read-only="true" />
	             <tx:method name="exist*" propagation="SUPPORTS" read-only="true" />
		</tx:attributes>
	</tx:advice> 

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
	<bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	   <property name="dataSource" ref="dataSource" />
	</bean>
  <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <!-- 自动扫描mapping.xml文件 -->
    <property name="mapperLocations" value="classpath:com/zit/**/mapping/*.xml"></property>
    <!-- mybatis配置文件 -->
    <property name="configLocation"  value="classpath:mybatis-config.xml"></property> 
  </bean>
  <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.zit.zVision.vehiclePassRecord.dao,com.zit.zVision.fvms.dao,com.zit.cac.dao,com.zit.zVision.trajectory.dao"></property>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
  </bean>
</beans>

       其次,编写 spring 连接 sql server 数据库的配置文件 spring-mybatis-mssql.xml,需要注意的是,在这个配置文件里面配置了两套数据源 dataSourceIacs和dataSourceTis,且需要在运行的时候才指定到底使用哪个数据库。

<?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:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context-3.1.xsd 
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
 http://cxf.apache.org/jaxws 
 http://cxf.apache.org/schemas/jaxws.xsd">
 
  <!-- 自动扫描 -->
  <context:component-scan base-package="com.zit">
        <context:exclude-filter type="annotation" 
       		expression="org.springframework.stereotype.Controller" />
   </context:component-scan>
   
  <!-- 配置数据库连接 -->
  <bean id="dataSourceTis" class="com.alibaba.druid.pool.DruidDataSource"  destroy-method="close">
    <property name="driverClassName" value="${mssqldriver}" />
    <property name="url" value="${tisurl}${tisdbName}" />
    <property name="username" value="${tisusername}" />
    <property name="password" value="${tispassword}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${maxActive}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${maxWait}"></property>
    <!-- 解决长时间不连接,连接失败问题 -->
    <property name="testOnBorrow" value="${testOnBorrow}"></property>
    <property name="testOnReturn" value="${testOnReturn}"></property>
    <property name="testWhileIdle" value="${testWhileIdle}"></property>
    <property name="validationQuery" value="${mssqlvalidationQuery}"></property>
    
    <!-- 打开removeAbandoned功能 -->
    <property name="removeAbandoned" value="${removeAbandoned}" />
    <!-- 1800秒,也就是30分钟 -->
    <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
    <!-- 关闭abanded连接时输出错误日志 -->
    <property name="logAbandoned" value="${logAbandoned}" />

    <!-- 监控数据库 -->
    <property name="proxyFilters">
	    <list>
	       <ref bean="statfilterMssql" />
	        <ref bean="logFilterMssql" />
	    </list>
	</property>
    <property name="filters" value="${filters}" />
  </bean>
  <bean id="dataSourceIacs" class="com.alibaba.druid.pool.DruidDataSource"  destroy-method="close">
    <property name="driverClassName" value="${mssqldriver}" />
    <property name="url" value="${iacsurl}${iacsdbName}" />
    <property name="username" value="${iacsusername}" />
    <property name="password" value="${iacspassword}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxActive" value="${maxActive}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWait" value="${maxWait}"></property>
    <!-- 解决长时间不连接,连接失败问题 -->
    <property name="testOnBorrow" value="${testOnBorrow}"></property>
    <property name="testOnReturn" value="${testOnReturn}"></property>
    <property name="testWhileIdle" value="${testWhileIdle}"></property>
    <property name="validationQuery" value="${mssqlvalidationQuery}"></property>
    
    <!-- 打开removeAbandoned功能 -->
    <property name="removeAbandoned" value="${removeAbandoned}" />
    <!-- 1800秒,也就是30分钟 -->
    <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
    <!-- 关闭abanded连接时输出错误日志 -->
    <property name="logAbandoned" value="${logAbandoned}" />

    <!-- 监控数据库 -->
    <property name="proxyFilters">
	    <list>
	     	<ref bean="statfilterMssql" />
	        <ref bean="logFilterMssql" />
	    </list>
	</property>
    <property name="filters" value="${filters}" />
  </bean>
  <!-- 下面的是切换数据库的自定义类 -->
    <bean id="multipleDataSource" class="com.zit.zVision.vimm.util.MultipleDataSource">
        <!--默认的数据源-->
	<property name="defaultTargetDataSource" ref="dataSourceTis"></property>
	<property name="targetDataSources">
		<map>
		    <entry key="dataSourceTis" value-ref="dataSourceTis"></entry>
		    <entry key="dataSourceIacs" value-ref="dataSourceIacs"></entry>
		</map>
	</property>
	</bean>

  <!-- 慢SQL记录 *start*-->
    <bean id="statfilterMssql" class="com.alibaba.druid.filter.stat.StatFilter">
        <property name="mergeSql" value="true" />
        <property name="slowSqlMillis" value="1000" />
        <property name="logSlowSql" value="true" />
    </bean>

    <bean id="logFilterMssql" class="com.alibaba.druid.filter.logging.Log4jFilter">
        <!-- <property name="resultSetLogEnabled" value="false" /> -->
        <!-- <property name="statementExecutableSqlLogEnable" value="true" /> -->
    </bean>
    
    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
	<bean id="transactionManagerMssql"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	   <property name="dataSource" ref="multipleDataSource" />
	</bean>
  <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
  <bean id="sqlSessionFactoryMssql" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="multipleDataSource" />
    <!-- 自动扫描mapping.xml文件 -->
    <property name="mapperLocations" value="classpath:com/zit/**/vimm/**/mapping/*.xml"></property>
    <!-- mybatis配置文件 -->
	<property name="configLocation"  value="classpath:mybatis-config-mssql.xml"></property> 
  </bean>
 

  <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.zit.zVision.vimm.tis.dao,com.zit.zVision.vimm.iacs.dao"></property>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryMssql"></property>
  </bean>
	
</beans>

        其中,在这个配置文件中,配置了一个切换数据库的自定义类 MultipleDataSource

public class MultipleDataSource extends AbstractRoutingDataSource{

	private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();

	public static void setDataSourceKey(String dataSource){
		dataSourceKey.set(dataSource);
	}
	
	@Override
	protected Object determineCurrentLookupKey() {
		return dataSourceKey.get();
	}

}

2.4 编写 mybatis 配置文件

        编写两套 mybatis 的配置文件,由于我的分页查询使用的是 PageHelper,所以需要在配置文件里面配置相应的标签

        1、首先编写 mysql mybatis 配置文件 mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
        <setting name="callSettersOnNulls" value="true"/>
        <setting name="logImpl" value="LOG4J" />
    </settings>
	<!-- 别名 -->
	<typeAliases>
		<package name="com.zit.cac.entity"/>
	</typeAliases>
	
	<!-- MyBatis实现分页插件 -->
    <plugins>              
	    <plugin interceptor="com.github.pagehelper.PageInterceptor">    	
	    	<!-- 其中sqlserver对应2005、2008-->
	        <property name="helperDialect" value="mysql"/>
	        <property name="offsetAsPageNum" value="false"/>
	        <property name="rowBoundsWithCount" value="false"/>
	        <property name="pageSizeZero" value="true"/>
	        <property name="reasonable" value="true"/>
	        <property name="supportMethodsArguments" value="false"/>
	        <property name="returnPageInfo" value="none"/>
	    </plugin>
	</plugins>
	
    
</configuration>

       然后编写 sql servermybatis 配置文件 mybatis-config-mssql.xml,一开始配置的只有一个配置文件,发现调用后台的数据库时一直报错,花了上午半天的时间,才发现他们的 helperDialect 不同的数据库需要不同的配置,所以这点要注意一下。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
        <setting name="callSettersOnNulls" value="true"/>
        <setting name="logImpl" value="LOG4J" />
    </settings>
	<!-- MyBatis实现分页插件 -->
    <plugins>              
	    <plugin interceptor="com.github.pagehelper.PageInterceptor">	    
	    	<!-- 其中sqlserver对应2005、2008-->
	        <property name="helperDialect" value="sqlserver"/>
	        <property name="offsetAsPageNum" value="false"/>
	        <property name="rowBoundsWithCount" value="false"/>
	        <property name="pageSizeZero" value="true"/>
	        <property name="reasonable" value="true"/>
	        <property name="supportMethodsArguments" value="false"/>
	        <property name="returnPageInfo" value="none"/>
	    </plugin>
	</plugins>
    
</configuration>

2.5 修改 web.xml

        在 web.xml 中配置相应标签,加载 spring 的配置文件

2.6 设定数据源

        在 service 层设定数据源,查询数据,如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐的小三菊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值