从我们接触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. 2013第四届蓝桥杯C/C++ B组

    题目标题: 高斯日记:Excel 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示 ...

  2. Mac下基于testrpc和truffle的以太坊智能合约开发环境搭建

    原文地址:石匠的blog truffle是一个基于Javascript开发的一套智能合约开发框架,使用Solidity语言编写合约.truffle有一套自动的项目构建机制,集成了开发,测试和部署的各个 ...

  3. 阿里云解析记录应对家里动态IP

    <?php #需要配置的项 define('ACCESSKEYID',''); #阿里云用户密钥ID 获取方法 https://help.aliyun.com/knowledge_detail/ ...

  4. linux命令系列 stat & touch

    1. stat - display file or file system status stat命令主要用于显示文件或文件系统的状态,详细信息 事实上,stat命令显示的是文件的I节点信息.Linu ...

  5. 第二阶段Sprint冲刺会议10

    进展:把所有功能整合到主界面,结果导致视频只能播放不能录制,闹钟加不进去,导致闹钟功能差点不能用,放弃整合.

  6. 关于‘1001.A+B Format (20)’的解题报告

    1001.A+B Format(20) 首先要感谢一下指导我github上传问题的小伙伴们,捣腾了一整天我终于摸到了一点门路,真的谢谢你们. 小豪的github 问题描述: Calculate a + ...

  7. 停止ipv6

    在Centos5.5默认的状态下,ipv6是被启用的.因为我们不使用ipv6,所以,可以停止ipv6,以最大限度地保证安全和快速.首先确认一下ipv6是不是处于被启动的状态.[root@sample ...

  8. 高可用集群(crmsh详解)http://www.it165.net/admin/html/201404/2869.html

    crmsh是pacemaker的命令行接口工具,执行help命令,可以查看shell接口所有的一级命令和二级命令,使用cd 可以切换到二级子命令的目录中去,可以执行二级子命令 在集群中的资源有四类:p ...

  9. poj 3254(状态压缩DP)

    poj  3254(状态压缩DP) 题意:一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相 ...

  10. Java词频统计

    public class WordCount { public static void main(String[] args) { String[] stopWords = { "" ...