简谈:SpringMVC + Mybatis 配置多数据源

1,660 阅读2分钟

工作原因,甲方需要同步我们项目的部分数据,对方甩过来一个Oracle 账号、密码、及IP端口号。先记录下自己配置双数据源的具体流程。

一.JDBC文件配置

本人项目使用sqlserver2008版本数据库:

#sqlserver 本项目实际数据库
driver=
url=
username=
password=

#oracle 需要同步数据的甲方甩来的数据库
jdbc.driver=
jdbc.url=
jdbc.username=
jdbc.password=

这个很简单,无需详述。

二.Mybatis.xml新增第二个数据源配置

<!-- 本项目 sqlserver2008 数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${driver}" />  
        <property name="url" value="${url}" />  
        <property name="username" value="${username}" />  
        <property name="password" value="${password}" />   
    </bean>  
    
    <!-- 客户的Oracle数据源 -->
     <bean id="dataSource_sq2" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${jdbc.driver}" />  
        <property name="url" value="${jdbc.url}" />  
        <property name="username" value="${jdbc.username}" />  
        <property name="password" value="${jdbc.password}" />
        <property name="validationQuery" value="select * from dual" />    
    </bean>  
    
这一步结束后需要注意:目前我们有两个数据源需要连接但是只有一个dataSource,所以下面需要统一下:


  <!--统一的dataSource-->
<bean id="**dynamicDataSource**" class="com.javen.datasource.DynamicDataSource" >
    <property name="targetDataSources">
        <map key-type="java.lang.String">
            <!--通过不同的key决定用哪个dataSource-->
            <entry value-ref="dataSource" key="dataSource_sq1"></entry>
            <entry value-ref="dataSource_sq2" key="dataSource_sq2"></entry>
        </map>
    </property>
    <!--设置默认的dataSource-->
    <property name="**defaultTargetDataSource**" ref="dataSource">
    </property>
</bean>

当然sql连接工厂也需要相应更改:确保映射到同一个dataSource环境

 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="**dynamicDataSource**" />  
        <property name="mapperLocations" value="classpath:com/javen/mapping/*.xml"></property>  
    </bean>  
  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.javen.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>  
  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="**dynamicDataSource**" />  
    </bean> 

接下来至关重要一步是:手写一个数据源切换类。好比一个开关,开关切换到A即连接A数据资源,开关切换到B即连接B数据资源。话不多说代码如下:

在这里插入图片描述

   package com.javen.datasource;
    
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    
    	public class DynamicDataSource extends AbstractRoutingDataSource {
    		 
    		 
    		@Override
    		protected Object determineCurrentLookupKey() {
    			return DataSourceContextHolder.getDbType();
    		}
    
    }

 package com.javen.datasource;
    
    public class DataSourceContextHolder {
    	private static final ThreadLocal<String> contextHolder =new ThreadLocal<>();
    	 public static void setDbType(String dbType){
    		 contextHolder.set(dbType);
    	 }
	 
	 public static String getDbType(){
		 return ((String)contextHolder.get());//获取数据库连接
	 }
	 public static void clearDbType(){
		 contextHolder.remove();  //关闭数据库连接
	 }

}

切换步骤:1.在指定需要连接第三方数据库的操作前切换数据源 2.切换类根据数据源ID连接指定数据库 3.CRUD任务处理完成后进行 数据连接关闭,不然会影响后续操作 代码如下:

//		            切换到指定数据源
//					DataSourceContextHolder.setDbType("dataSource_sq2");
//					parkRecordOracleService.insertRecord(parkRecordOracle);
//					System.out.println("-----------------------------------------离开插入第三方数据库成
//	 功");
//					DataSourceContextHolder.clearDbType();  // 关闭数据库连接

全部完毕; 个人建议:连接第三方库时最好放在try-catch 块内,以免影响自己项目本身。

以上方法及代码只针对本人实际生产环境,仅供各位同仁参考,有不合适的地方欢迎批评指正!

在这里插入图片描述