从我们接触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. Windows下的ROUGE文本测评工具基本安装

    需要的安装包: rouge1.5.5:https://pan.baidu.com/s/1B7-LYn1lZKC8f51yXxNK9w Strawberry Perl :http://strawberr ...

  2. 图片人脸检测(OpenCV版)

    图片人脸检测 人脸检测使用到的技术是OpenCV,上一节已经介绍了OpenCV的环境安装,点击查看. 功能展示 识别一种图上的所有人的脸,并且标出人脸的位置,画出人眼以及嘴的位置,展示效果图如下: 多 ...

  3. 完整Highchart JS示例

    线性: $.ajax({ type:'post', url:appPages.urlListTjrll, cache:false, data:{year:year,month:month},// // ...

  4. python下graphviz安装

    参考链接:https://blog.csdn.net/u013250416/article/details/72790754 1.安装Graphviz 在graphviz的官网(网址:http://w ...

  5. 08慕课网《进击Node.js基础(一)》事件events

    引用events模块中的EventEmitter 事件的监听和发射 相同的事件发射数量有限,可以通过setMaxListeners设置峰值 var EventEmitter = require('ev ...

  6. b4

    吴晓晖(组长) 过去两天完成了哪些任务 昨天FloatingActionButton和权限获取调整 今天复习,没写东西,晚点有空了写 展示GitHub当日代码/文档签入记录 接下来的计划 推荐算法 还 ...

  7. 《TCP/IP 详解 卷1:协议》第 10 章:用户数据报协议

    引言 UDP 稍微扩展了IP协议,使得包可以在进程间传送,而不仅仅是在主机件.--<CSAPP> IP 数据报是指 IP 层端到端的传输单元.分组(packet)是 IP 层和链路层的传输 ...

  8. Think In Java读书笔记:内部类覆盖及其初始化

    本文相关章节:第十章 内部类 10.10 内部类可以被覆盖吗 在读至本节第二个范例代码时(及下方的代码),我对输出结果中的第一个“Egg.Yolk()”很不理解,为什么它会第一个地方输出. 我起初认为 ...

  9. 蜗牛慢慢爬 LeetCode 15. 3Sum [Difficulty: Medium]

    题目 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...

  10. 使用GatewayWorker 开发个即时聊天demo

    前言: 上手册以示尊重:https://www.kancloud.cn/walkor/gateway-worker/326138: https://www.cnblogs.com/fuqiang88/ ...