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. CSS常见技巧

    一.CSS Sprite(雪碧图|精灵图)指什么? 有什么作用? CSS雪碧 即CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图像和背景图片合并到一张图片上,然后利 ...

  2. [django]数据导出excel升级强化版(很强大!)

    不多说了,原理采用xlwt导出excel文件,所谓的强化版指的是实现在网页上选择一定条件导出对应的数据 之前我的博文出过这类文章,但只是实现导出数据,这次左思右想,再加上网上的搜索,终于找出方法实现条 ...

  3. [斜率优化DP]【学习笔记】【更新中】

    参考资料: 1.元旦集训的课件已经很好了 http://files.cnblogs.com/files/candy99/dp.pdf 2.http://www.cnblogs.com/MashiroS ...

  4. 从myeclipse导入eclipse,不能识别为web项目(java项目转为web项目)

    1.进入项目目录,找到.project文件,打开. 2.找到<natures>...</natures>代码段. 3.在第2步的代码段中加入如下标签内容并保存:         ...

  5. .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点

    2016年7月10日,我们在生产环境中上线了第一个运行于Linux上的ASP.NET Core站点,这是一个简单的提供后端服务的ASP.NET Core Web API站点. 项目是在Windows上 ...

  6. ASP.NET MVC 视图(二)

    ASP.NET MVC 视图(二) 前言 上篇中对于视图引擎只是做了简单的演示,对于真正的理解视图引擎的工作过程可能还有点模糊,本篇将会对由MVC框架提供给我们的Razor视图引擎的整个执行过程做一个 ...

  7. Axure原型制作规范

    一. 名词定义: Sitemap 导航图 Widgets 组件 Master 库 Label 控件名 Interactions 交互动作 Annotations 注释 Location and siz ...

  8. AngularJs之六(服务)

    服务:AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用.AngularJS 内建了30 多个服务. 最常用的服务:$location  服务,  $http 服务 ...

  9. 1.Kali安装到移动硬盘或者U盘中~Linux系通用方法(包括Android)

    0.1.保证这个服务必须启动(虚拟机服务最好都启动) 0.2.看看U盘接口类型是否对应 1.安装第一步 2.安装第二步,选择kali镜像 3.设置存放位置(上面的名字无所谓,最后不会用它的,虚拟机只是 ...

  10. Git(最基本使用远程仓库:github)-V1.0

    所有操作的根目录是:D:/zqzGit文件夹,这个目录也是git仓库 git bash清屏  clear  1.安装(略)  2.安装后记得配置: $ git config --global user ...