码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2014-05-01 18:20:41      阅读:569      评论:0      收藏:0      [点我收藏+]

标签:spring多数据源   struts+spring+ibatis   

一、概述

基于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
		return null;
	}
}

5、编写Spring的配置文件配置多个数据源

5.1、读取数据源信息的配置,这里我们是从tomcat容器的conf目录下读取jdbc.properties配置文件,该配置文件信息在后面给出。

<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>
					file:${webapp.root}\..\..\conf/jdbc.properties
				</value>
			</list>
		</property>
	</bean>

5.2、配置数据源的配置

<!-- 数据源1配置 -->
	<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc1.url}" />
		<property name="username" value="${jdbc1.username}" />
		<property name="password" value="${jdbc1.password}" />
	</bean>

	<!-- 数据源1配置 -->
	<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc2.url}" />
		<property name="username" value="${jdbc2.username}" />
		<property name="password" value="${jdbc2.password}" />
	</bean>

	<!-- 编写spring 配置文件的配置多数源映射关系 -->
	<bean class="com.song.datasource.DynamicDataSource" id="dataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry value-ref="dataSource1" key="1"></entry>
				<entry value-ref="dataSource2" key="2"></entry>
			</map>
		</property>
		<!--默认采用dataSource1-->
		<property name="defaultTargetDataSource" ref="dataSource1">
		</property>
	</bean>

说明:上述为两个数据库实例的配置信息,第三段中编写Spring配置文件的多数据源映射关系是关键,这里映射dataSource1和dataSource2对应的key值为1和2,在我们程序中就可以根据这两个key值来做判断,同时还配置了默认的数据源为dataSource1.

5.3、jdbc.properties配置信息如下,这里分别配置了orcl和n8web两个oracle实例的配置信息,账户和口令均为n8_web,在创建数据库表空间和用户时随便取名称。

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc1.url=jdbc:oracle:thin:@127.0.0.1:1521:n8web
jdbc1.username=n8_web
jdbc1.password=n8_web

jdbc2.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
jdbc2.username=n8_web
jdbc2.password=n8_web

说明:从上述配置文件可以看出,dataSource1数据源对应的是n8web这个实例,dataSource2对应的是orcl实例。两个实例创建的账户信息均为n8_web(随意)

四、运行结果如下:

mamicode.com,码迷

-1

上图中,前期准备工作中,在数据源1的数据库实例中插入了11条数据,在数据源2的实例中插入了8条数据,下面点击【数据源选择】查看输出的数据列表是否正确,如下:

mamicode.com,码迷

图-2

选择【数据源2】时,查询出来的数据如下:

mamicode.com,码迷

-3

采用PL/SQL工具来验证下是否正确,两个数据库实例中的数据如下:

mamicode.com,码迷

-4

mamicode.com,码迷

图-5

结论:测试的结果是正确的,能根据条件达到动态切换数据源的目的


源码配置文件等下载:(包含源码、各种配置文件、数据库脚本等)

多数据源动态切换

基于Struts2 Spring ibatis Oracle10g架构 多数据源动态切换实例,码迷,mamicode.com

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

标签:spring多数据源   struts+spring+ibatis   

原文地址:http://blog.csdn.net/xuzheng_java/article/details/24802353

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!