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. 敏捷转型历程 - Sprint3 Grooming

    我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...

  2. SSIS 包部署 Package Store 后,在 IS 中可以执行,AGENT 执行却报错

    可以执行 SSIS Package ,证明用 SSIS Package 的账户是可以执行成功的.SQL Server Agent 默认指定账号是 Network Service. 那么可以尝试一下将 ...

  3. uboot环境配置

    uboot环境配置 通过配置uboot让它在启动过程中从tftp获取内核和设备树,并从在加载内核之后把通过启动参数将"从nfs挂载根文件系统"传入内核.这个配置主要是通过uboot ...

  4. FineReport:关于扩展行列求各种条件下的函数运用

    最简单的扩展列,扩展行的求"最大,最小,平均"值的例子 设计图 效果图 相关函数 =MAX(B2:E2) =MIN(B2:E2) =AVERAGE(B2:E2) 这个是(满足条件) ...

  5. 深入理解Spring MVC

    如何让一个普通类成为Controller? 方案一:实现接口Controller 解析:handleRequest(request,response) 方案二:继承AbstractController ...

  6. 用Taurus.MVC 做个企业站(下)

    前言: 上一篇完成了首页,这一篇就把剩下的几个功能给作了吧. 包括文章列表.文章详情和产品展示. 1:文章列表: 原来的ArticleList.aspx 1:现在的articlelist.html 除 ...

  7. webpack解惑:多入口文件打包策略

    本文是我用webpack进行项目构建的实践心得,场景是这样的,项目是大型类cms型,技术选型是vue,只支持chrome,有诸多子功能模块,全部打包在一起的话会有好几MB,所以最佳方式是进行多入口打包 ...

  8. CSS currentColor 变量的使用

    CSS中存在一个神秘的变量,少有人知自然也不怎么为人所用.它就是crrentColor变量(或者说是CSS关键字,但我觉得称为变量好理解些). 初识 它是何物?具有怎样的功效?它从哪里来?带着这些疑问 ...

  9. ABP源码分析三十一:ABP.AutoMapper

    这个模块封装了Automapper,使其更易于使用. 下图描述了改模块涉及的所有类之间的关系. AutoMapAttribute,AutoMapFromAttribute和AutoMapToAttri ...

  10. C# 面向对象基础

    面向对象编程OOP(Object-Oriented Programming) 类和对象 类是对象的定义,对象是类的实现. [属性集信息] [类修饰符] class 类名 [:类基] //定义类的语法格 ...