Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性。而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据。

Spring配置多数据源的方式和具体使用过程。 
Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况: 
一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。 
二是,非表级上的跨数据库。即,多个数据源不存在相同的表。 
Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。 
具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。

步骤如下:

一、动态配置多数据源 
1. 数据源的名称常量类:

 package com.login;

 public class DataSourceConst {

     public static final String Admin = "admin";
public static final String User = "user";
}

2. 建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称:

package com.login;

public class DataSourceContextHolder {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();//线程本地环境

    //设置数据源类型
public static void setDataSourceType(String dataSourceType)
{
contextHolder.set(dataSourceType);
} //获取数据源类型
public static String getDataSourceType()
{
return contextHolder.get();
} //清除数据源类型
public static void clearDataSourceType()
{
contextHolder.remove();
}
}

3. 建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方法 determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串:

 package com.login;

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

 public class DynamicDataSource extends AbstractRoutingDataSource {

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

4. 编写spring的配置文件配置多个数据源

 <?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- spring 读取数据库配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean> <bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="autoCommitOnClose" value="true"/>
<property name="checkoutTimeout" value="${cpool.checkoutTimeout}"/>
<property name="initialPoolSize" value="${cpool.initialPoolSize}"/>
<property name="minPoolSize" value="${cpool.minPoolSize}"/>
<property name="maxPoolSize" value="${cpool.maxPoolSize}"/>
<property name="maxIdleTime" value="${cpool.maxIdleTime}"/>
<property name="preferredTestQuery" value="${cpool.preferredTestQuery}"/>
<property name="acquireIncrement" value="${cpool.acquireIncrement}"/>
<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}"/>
</bean> <bean id="adminDataSource" parent="parentDataSource">
<property name="jdbcUrl" value="${jdbc.url}"></property>
</bean>
<bean id="userDataSource" parent="parentDataSource">
<property name="jdbcUrl" value="${jdbc.url1}"></property>
</bean> <bean id="dataSource" class="com.login.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="adminDataSource" key="admin"></entry>
<entry value-ref="userDataSource" key="user"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="adminDataSource"></property>
</bean> <!-- Spring提供的iBatis的SqlMap配置 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean> </beans>

5.配置dao

 <bean name="loginDao" class="com.login.LoginDao">
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
<bean name="loginService" class="com.login.LoginService">
<property name="loginDao" ref="loginDao"></property>
</bean>

6.编写测试类

 BeanFactory beanFactory = (BeanFactory)(new ClassPathXmlApplicationContext("applicationContext.xml"));
LoginDao loginDao = (LoginDao)beanFactory.getBean("loginDao");
DataSourceContextHolder.setDataSourceType(DataSourceConst.Admin); loginDao.getUserInfo(); DataSourceContextHolder.setDataSourceType(DataSourceConst.User); loginDao.getUserInfo();

Spring+ibatis动态管理数据源的更多相关文章

  1. Spring+Mybatis动态切换数据源

    功能需求是公司要做一个大的运营平台: 1.运营平台有自身的数据库,维护用户.角色.菜单.部分以及权限等基本功能. 2.运营平台还需要提供其他不同服务(服务A,服务B)的后台运营,服务A.服务B的数据库 ...

  2. Spring MVC动态切换数据源(多数据库类型)

    最近由于项目需求,需要将Sql Server 和 Mysql 两种数据库整合到一个项目,项目的用到的框架是SSM. 因此尝试了利用AOP切面来切每次执行的Servcie方法,根据Service所在的包 ...

  3. spring security动态管理资源结合自定义登录页面

    如果想将动态管理资源与自定义登录页面一起使用,最简单的办法就是在数据库中将登录页面对应的权限设置为IS_AUTHENTICATED_ANONYMOUSLY. 因此在数据库中添加一条资源信息. INSE ...

  4. Spring AOP动态切换数据源

    现在稍微复杂一点的项目,一个数据库也可能搞不定,可能还涉及分布式事务什么的,不过由于现在我只是做一个接口集成的项目,所以分布式就先不用了,用Spring AOP来达到切换数据源,查询不同的数据库就可以 ...

  5. spring+ibatis事务管理配置

    <!-- 配置事务管理器 --> <bean id="transactionManager"         class="org.springfram ...

  6. spring动态创建数据源

    在最近的项目业务中,需要在程序的运行过程中,添加新的数据库添链接进来,然后从新数据库链接中读取数据. 网上查阅了资料,发现spring为多数据源提供了一个抽象类AbstractRoutingDataS ...

  7. spring + ibatis 多数据源事务(分布式事务)管理配置方法(转)

    spring + ibatis 多数据源事务(分布式事务)管理配置方法(转) .我先要给大家讲一个概念:spring 的多数据源事务,这是民间的说法.官方的说法是:spring 的分布式事务.明白了这 ...

  8. Spring 管理数据源

    Spring 管理数据源 不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spring中,数据连接是通过数据源获得的.在以往的应用中,数据源一般是Web应用服务器提供的.在Spring中,你不 ...

  9. Spring + Mybatis 项目实现动态切换数据源

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. ...

随机推荐

  1. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  2. iOS - 模态Model视图跳转和Push视图跳转的混合需求实现原理

    在研发中总会遇到一些莫名的需求,本着存在即合理的态度跟大家分享一下"模态Model视图跳转和Push视图跳转的需求实现",本文仅仅传授研发技术不传授产品以及UE的思想,请大家合理对 ...

  3. 张高兴的 UWP 开发笔记:汉堡菜单进阶

    不同于Windows 8应用,Windows 10引入了"汉堡菜单"这一导航模式.说具体点,就拿官方的天气应用来说,左上角三条横杠的图标外加一个SplitView控件组成的这一导航 ...

  4. Android 指纹认证

    安卓指纹认证使用智能手机触摸传感器对用户进行身份验证.Android Marshmallow(棉花糖)提供了一套API,使用户很容易使用触摸传感器.在Android Marshmallow之前访问触摸 ...

  5. (转) 将ASP.NET Core应用程序部署至生产环境中(CentOS7)

    原文链接: http://www.cnblogs.com/ants/p/5732337.html 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Cor ...

  6. Linux系统中的Device Mapper学习

    在linux系统中你使用一些命令时(例如nmon.iostat 如下截图所示),有可能会看到一些名字为dm-xx的设备,那么这些设备到底是什么设备呢,跟磁盘有什么关系呢?以前不了解的时候,我也很纳闷. ...

  7. 【C#】获取网页内容及HTML解析器HtmlAgilityPack的使用

    最近经常需要下载一些东西,而这个下载地址又会经过层层跳转,每个页面上都有很多广告,烦不胜烦,所以做了一个一键获得最终下载地址的小工具.使用C#,来获取网页内容,然后通过HtmlAgilityPack获 ...

  8. mono for android 读取网络远程图片

    布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=& ...

  9. Nginx服务器之Nginx与tomcat结合访问jsp

    本文使用linux centos系统 本文概述: JSP是一种动态网页技术标准.使用的方式是在HTML文件中插入程序段和JSP标记,而形成JSP文件.使用JSP开发WEB应用可以跨平台开发.但jsp需 ...

  10. 苹果手机Safari无痕浏览模式下系统登录成功但是页面不跳转

    昨天下午,测试提了一个bug,问题是:在苹果手机Safari无痕浏览模式下系统登录成功但是页面不跳转. 思前想后找了半天没思路,后来经过同事的点拨,说可能是禁用了cookie之类的,反正我也没思路就顺 ...