基于Struts2 Spring ibatis Oracle10g架构 多数据源动态切换实例(一)

2014-11-23 22:15:29 · 作者: · 浏览: 2

一、概述

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

Spring配置多个数据源的方式和具体使用过程,Spring对于多数据源,以数据库表为参照,大体上可以分为两大类情况:

1、表级上的跨数据库,即对于不同的数据库却有不相同的表(表名和表结构完全相同)。

2、非表级上的跨数据库,即多个数据源不存在相同的表。

Spring2.x的版本中采用Proxy模式,就是在方案中实现一个虚拟的数据源,并且采用它来封装数据源选择逻辑,这样就可以有效的地将数据源选择逻辑从Client中分离出来,Client提供选择所需上下文,由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。具体实现就是,虚拟的DataSource仅需要继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数选择逻辑。


二、前期准备

1、搭建好ssi的web架构

2、创建好oracle数据库实例,该实例中创建实例为orcl和n8web两个数据库实例,并且创建好表空间和对应的数据库表

3、配置好tomcat容易,能正常发布web工程。

4、每个实例中创建如下脚本的表和添加数据,为了区分web能动态的切换数据源,请在两个实例中添加不同的数据即可。

CREATE TABLE UserInfo
(
id        NUMBER(10) NOT NULL,
username  VARCHAR(32),
password  VARCHAR(32),
emial     VARCHAR(15),
sex       VARCHAR(10),
brithday  NUMBER(32),
province  VARCHAR(32),
city      VARCHAR(32),
state     VARCHAR(32),
realname  VARCHAR(32),
college   VARCHAR(255),
highschool  VARCHAR(255),
gradeschool  VARCHAR(32),
regtime      NUMBER(32),
logintime    NUMBER(32),
PRIMARY KEY (id)
);

insert into UserInfo values(1,'zhangsan','123456','zhang@163.com','男',null,'湖南','长沙','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(2,'zhangsan02','123456','zhang@163.com','女',null,'北京','北京','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(3,'zhangsan03','123456','zhang@163.com','男',null,'湖南','长沙','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(4,'zhangsan04','123456','zhang@163.com','女',null,'深圳','深圳','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(5,'zhangsan05','123456','zhang@163.com','男',null,'湖南','长沙','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(6,'zhangsan06','123456','zhang@163.com','女',null,'广东','广州','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(7,'zhangsan07','123456','zhang@163.com','男',null,'湖南','长沙','健康','张三','北京大学',null,null,null,null);
insert into UserInfo values(8,'zhangsan08','123456','zhang@163.com','女',null,'湖北','武汉','健康','张三','北京大学',null,null,null,null);

三、实现步骤

1、搭建基于struts2+spring+ibatis+oracle10g的web架构(该过程略)

2、创建数据源的名称常量类

public class DataSourceConst {
	public static final String Admin="1";
	public static final String User="2";
}
3、建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称

public class DataSourceContextHolder {
	private static final ThreadLocal contextHolder = new ThreadLocal(); // 线程本地环境
	// 设置数据源类型
	public static void setDataSourceType(String dataSourceType) {
		contextHolder.set(dataSourceType);
	}
	// 获取数据源类型   
	public static String getDataSourceType() {
		return (String) contextHolder.get();
	}
	// 清除数据源类型
	public static void clearDataSourceType() {
		contextHolder.remove();
	}
}

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

public class DynamicDataSource extends AbstractRoutingDataSource {

	@Override
	protected Object determineCurrentLookupKey() {
		return DataSourceContextHolder.getDataSourceType();
	}
	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		re