从我们接触Javaweb开始,ssh框架或者ssm等或许是惊叹于框架的强大之处还是自身的迷茫,一直没有注意到一个问题就是:在我的项目中在spring中所配置的数据源都是指向单一数据库,都是单数据源,一个指向数据库的url,数据库驱动,用户名密码等的配置。但是随着自己工作时间的延长在新公司我接触到了新的问题。多数据源的配置和使用。

在实际的开发中有很多时候我们是要与其他公司进行合作,有的合作公司会给咱们一系列的数据接口我们只需要做好数据展示等工作,但是有的公司则是会向我们开放一个数据库的端口,让我们可以对数据库进行查询操作。而且这一部分功能是嵌入在我们原来的系统中的,这时候就会发现我们在我们的项目中用到了两个数据源,在这之前我们好像对于多数据源的开发毫无经验。

经过公司大神的指导以及自己的百度查询结果。get到了这个多数据源开发的技能,首先在spring的配置文件中配置自己的与数据库进行连接的bean,需要几个,有几个配几个,然后就是需要写一个类,这个类就是实现多数据源切换的关键了。这个类需要继承spring提供的一个抽象类:org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,然后需要实现其中的一个方法:determineCurrentLookupKey这个方法的作用就是返回要使用的数据源的名称,注意这个操作是要与将来数据库中的其他配置联动的:

<bean id="multipleDataSource" class="com.base.multidb.MyDataSource">
        <property name="defaultTargetDataSource" ref="主数据源"/>
        <property name="targetDataSources">
            <map>
                <entry key=" 主数据源" value-ref="主数据源"/>
   <entry key=" 数据源1" value-ref="数据源1"/>

<entry key=" 数据源2" value-ref="数据源2"/>
            </map>
        </property>
    </bean>

在上面的配置中所用到的三个数据源(与数据库的连接bean)是自己所配置的存在的,在上面所配置的bean中defaulttargetDataSource代表的是主数据源即默认的数据源,下面的targetDataSources中所属的map中所配置的就是所有的数据源,有几个用到几个就配置几个,此时就理解了上面自己所写的实现spring提供的抽象类的方法的操作含义了,那个方法的主要目的就是返回一个所要使用的数据源的名称,而这个数据源的名称会去与所配置的map中所有数据源的key进行匹配,一致的数据源就会是这个线程操作所使用到的数据源,通过上面的操作基本上就可以实现多数据源的切换了,自己所实现的那个类其实就是一个数据源的代理对象,然后将这个对象传递给sqlsessionfactory即可进行数据库的相关操作获取sqlsession操作数据库了,

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="multipleDataSource"/>
<property name="mapperLocations">
<list>
  <value>classpath:com/mapper/*Mapper.xml</value>
  <value>classpath:com2/mapper/*/*Mapper.xml</value>
</list>
</property>
    </bean>

而在事物配置上也是,将代理数据源配置到事物中的DataSource即可

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="multipleDataSource" /> 
  </bean>

配置说完了,下面该代理数据源的实现了:

package com.base.multidb;

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

public class MyChangeDateSource extends AbstractRoutingDataSource{

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

public static void setDataSource(String useSource){
datasourceKey.set(useSource);
}

@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return datasourceKey.get();
}

}

这个操作没有多少可说的,因为我也不是特别懂,不过还是需要说两句ThreadLocal是在多线程环境中使用的,创建一个对象只属于当前线程并在当前线程中共享,set方法就是我们在开发中进行业务逻辑操作之前需要进行数据源切换的一个操作方法。而最后一个方法就是继承spring提供的抽象类后要求必须实现的一个方法,这个方法中需要进行一个操作,就是返回你所需要使用的数据源的key(在配置文件中有配置)

在接下来说说具体的数据源切换的使用:

首先,这个数据源的切换操作所进行的位置个人认为是需要在action或者controller中进行的,因为service中一般都是一些业务逻辑操作一般是需要事物的(比如多数据操作,某一个出错的数据统一回滚)所以需要在Action中进行切换,如果写的不对望各位大神留言批判。

具体操作没什么:在action中进行数据库相关操作前加入一行代码:

MyChangeDateSource.setDataSource(""); 将所要切换的数据源的对应的key作为参数传递进去即可

这样这个key就保存在ThreadLocal的对象中,对于这个线程来说所使用的的数据源就一直都是正确所需要的数据源(因为这个controller方法作为后天的一个部分是在一个多线程环境中可能会有很多个线程都会进行访问,这样就将数据源匹配给对应的线程操作不会出现混乱)

最后要提一句:这里指的多数据源是广义上的数据源,即一个数据源就是指一个数据库服务器中的所有数据库,多数据源是指夸服务器的多个数据库的操作,如果仅仅是一个数据库服务器上的多个数据库的操作的话没有必要进行多数据源的配置。在进行同源(同一个数据库服务器)数据库进行操作的时候只需要在sql语句里面稍加变动即可,即在写表的时候不能直接写表名,而是需要:数据库
 【.】 该库下的表名 然后进行其他的数据库操作

JavaWeb中的多数据源开发的更多相关文章

  1. 如何在spring框架中解决多数据源的问题

    在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库.我们以往在spring和hibernate框架中总是配置一个数据源,因而sessi ...

  2. SpringSide 3 中的多数据源配置的问题

    在SpringSide 3 中,白衣提供的预先配置好的环境非常有利于用户进行快速开发,但是同时也会为扩展带来一些困难.最直接的例子就是关于在项目中使用多个数据源的问题,似乎很难搞.在上一篇中,我探讨了 ...

  3. 在javaweb中通过servlet类和普通类读取资源文件

    javaweb有两种方式读取资源文件 在Servlet中读取,可以使用servletContext,servletContext可以拿到web所有的资源文件,然后随便读,但是这种方法不常用,尽量少在S ...

  4. javaWeb中的文件上传下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  5. SSIS中出现数据流数据源假死状态的解决办法

    相信开发过Sql Server SSIS的人都遇到过在数据流中数据源假死的问题,特别是Excel Source特别容易假死,当job执行到数据流中的Excel Source时,既不报错也不执行,也没有 ...

  6. javaWeb中,文件上传和下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  7. JavaWeb中文件的上传和下载

    JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...

  8. 去哪网实习总结:JavaWeb中文传參乱码问题的解决(JavaWeb)

    本来是以做数据挖掘的目的进去哪网的.结构却成了系统开发... 只是还是比較认真的做了三个月.老师非常认同我的工作态度和成果... 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享给 ...

  9. JavaWeb零基础入门-02 开发环境安装

    大家好!我又来了,上一篇我们讲了一些基础概念:Html.Web服务器.数据库.Http和JavaWeb三大组件,它们是什么,有什么作用,都有了初步的了解.接下来我们进入学习JavaWeb的第一步,开发 ...

随机推荐

  1. BP神经网络算法推导

    目录 前置知识 梯度下降法 激活函数 多元复合函数求偏导的相关知识 正向计算 符号定义 输入层 隐含层 输出层 误差函数 反向传播 输出层与隐含层之间的权值调整 隐含层与输入层之间权值的调整 计算步骤 ...

  2. 金融科技行业 SDL(转载)

     都是一些检查项,值得借鉴,关键在于要能够落地 作者 沈发挺@美的金融科技下载打印版

  3. CocoaPods :为iOS程序提供依赖管理的工具(yoowei)

    修改于:2016.11.18   2017.1.10  2019.01.31 CocoaPods 源码 : https://github.com/CocoaPods/CocoaPods CocoaPo ...

  4. Scrum Meeting 7 -2014.11.13

    之前srcum没写好是我的错.以后会每天更新的. 老师反映之前项目小组从pdf中提取作者效果不好,我们讨论决定进行一定的优化.在整合测试的同时开始服务器程序部署. Member Today’s tas ...

  5. 《Spring2之站立会议6》

    <Spring2之站立会议6> 昨天,向主界面中加入语音功能部分的代码: 今天,查相关资料解决debug: 遇到问题,一些问题是得到解决了,但是一些还未被解决.

  6. NABCD模型分析

    1.N——need需求 目前,学习英语是所有学生会面临的问题.提高词汇量对学习英语是十分必要的,尤其是对大学生来说对手机的使用特别频繁,我们提高英语词汇量也应该把手机更好的利用起来,利用自己对手机的使 ...

  7. iOS-UICollectionViewLayout方法介绍

    注意:UICollectionView的自定义功能就是自己去实现UICollectionViewLayout的子类,然后重写相应的方法来实现Cell的布局 1.当布局首次被加载时会调用prepareL ...

  8. js dom学习

    创建dom元素 var oLi = document.creteElement('li'); //创建livar aLi = oUl.getElementsByTagName('li');oLi.in ...

  9. 事件ID:7026(“下列引导或系统启动驱动程序无法加载: cdrom”)的解决方法

     电脑没有安装光驱,而是使用USB光驱/虚拟光驱软件,每次开机后"事件查看器"都显示错误:"下列引导或系统启动驱动程序无法加载: cdrom"(事件ID:7 ...

  10. scala 有 + 运算符吗? - 03

    scala 有运算符吗? 答案是没有. package com.msym /** * Created by ACER on 2017/7/4. */ object Demo { def main(ar ...