什末是等级化数据集?我们为什末要关注它?
等级化数据集并不是一个新的概念 在客户控制信息系统的事务化数据表单中目录的文件中 以及常用的JAVA对象中都存在着等级化数据集 同样的它也很明显的存在于XML中在早期的XML 杂志中 我发表了一个观点程序员会受益于等级化数据抽即使他们的很多数据源是显着相关的(比如数据库包括MySQL Oracle SQL Server DB 等等)
在NET世界中有一个相似的观点来自于数据集概念虽然在我提议的等级化数据集和微软的数据集有很重要的不同但是很显然等级化数据集通过丰富的细节化处理增强了相关的抽象提取
这篇文章描述了Java API使用的分等级的数据集结构不同于二年前XML 学报参考您现在将会有可执行的代码片断通过运行它可以体验开始利用分等级的数据集虽然程序员能使用Java编码来访问各种各样的数据源以及构建最后的分等级的数据集这篇文章可以通过简单地组成预构造的关系适配器让您很容易的构建这些分等级的数据集关系适配器包括文件阅读器SQL阅读器存储过程的阅读器等等
您大概会问这些分等级的数据集的好处在哪里?虽然他们目前的作用还不是主导地位的但是在编程界等级结构数据集是相当有用的对于初学者一个完整的HTML页面所应具有的数据价值可以由一个等级结构数据集来满足在一个MVC 模型中一个servlet 控制器 能提供一个等级制度的数据集给JSP 页面这个页面可以轻松的作它需要做的 在数据准备方面它能被转换成XML 并直接地通过servlet控制器返回到访问者在应用方面等级结构数据集能被转换成Excel 文档在格式方面等级结构数据集能重定向为一个报告引擎或一个支持XML 数据的绘制图表的引擎
虽然文章的主要焦点是面向Java 程序员的Java 编程API等级结构数据集能被非NonJava 程序员相当有效地使用直接地从关系数据库和其它数据源同过使用像Tomcat这样的JEE 服务器获得XML HTML 或Excel 格式闲言少讲让我们研究一下等级结构数据集的结构以及看看这些数据集是怎样被获得的(当放松一下您的编程肌肉)
等级化数据结构
一种等级化数据结构能概念性地描述为如同Java API 或XML 或某一其它格式它最容易形象化地作为XML
<AspireDataSet>
<!—一组在根级别的key value 对>
<key>val</key>
<key>val</key>
<!—一组指定的循环 >
<loop name=loop>
</loop>
<loop name=loop>
</loop>
</AspireDataSet>
这是一套key/value 对给出的这套key/value 对能产生n 个独立的循环各个循环本质上来说是一个数据表这里术语循环 与表?±是同义的 我没有使用表 是因为人们可能会根据字面意思来只采用表作为从关系表中取出的的唯一数据被提及是行的集合(RowSet) 让我们更加接近地看一下循环的结构:
<loop name=loopname>
<row>
<!一组key value 对>
<key>val</key>
<key>val</key>
<!一组指定的循环>
<loop name=loopname>
</loop>
<!一组指定的循环>
<loop name=loopname>
</loop>
</row>
<row>
</row>
</loop>
这里唯一的没有配对的是列的结构列是期望的key/value对的集合这里列不仅包括key/value 对而且包括另外的一个n个独立循环的递归集引伸一下可以生成任意数量深度的树(或者我应该说任意的高度!)
Java中的等级化数据结构
在我用XML显示等级化数据的时候有一种可能性就是人们也许采取一个等级化数据集逐字的访问XML数据继而逐字地使用DOM继而在JVM 里面消耗很多的内存不过不必惊慌等级化数据集有它自己的Java API从而可以不使用DOM多数的时候只是向前遍历加载数据树下面是一个使用Java API 处理一个等级化数据集的例子:
package lgen;
import comaidata*;
/**
* 代表了一个等级化数据集
* 一个hds 是一个行的集合
* 你可以通过ILoopForwardIterator枚举这些行
* 你可以通过IMetaData 枚举各个列
* 一个hds 也是一个基于当前行得循环集
*/
public interface ihds extends ILoopForwardIterator
{
/**
*返回父级接口
* 如果没有父级接口则返回NULL
*/
public ihds getParent() throws DataException;
/**
* 基于当前行返回一系列的子循环名字ILoopForwardIteraor 确当前行是什末
*
*
* @see ILoopForwardIterator
*/
public IIterator getChildNames() throws DataException;
/**
* 通过给定的名字返回一个ihds 类型的Java子对象
*/
public ihds getChild(String childName) throws DataException;
/**
返回一个列这跟对一个行集合进行求和求平均很类似
*/
public String getAggregatevalue(String keyname) throws DataException;
/**
返回这个循环或者表的列名字
* @see IMetaData
*/
public IMetaData getMetaData() throws DataException;
/**
释放所有数据或表格循环使用的资源
*/
public void close() throws DataException;
}
简而言之Javaihds 接口描述了面向等级数据集的接口这个API允许你使用循环递归调用在运行时有个选项指定只有当他们被要求的时候才加载这些循环它也能够假定是仅仅向前还是随机遍历在往下继续以前 让我来介绍两个另外该API使用的接口ILoopForwardIterator 和ImetaData
如何在HDS中移动遍历一系列的行ILoopForwardIterator
package lgen;
import comaidata*;
public interface ILoopForwardIterator
{
/**
* 根据匹配的钥匙从当前的行中获取相应的值
*/
public String getvalue(final String key);
public void moveToFirst() throws DataException;
public void moveToNext() throws DataException;
public boolean isAtTheEnd() throws DataException;
}
IMetaData: 用来读取列名
package comaidata;
public interface IMetaData
{
public IIterator getIterator();
public int getColumnCount();
public int getIndex(final String attributeName)
throws FieldNameNotFoundException;
}
你如何获取一个等级数据集 从而你可以使用它?
现在我们知道了等级化数据集的结构 你如何来控制它呢?根据我的经验 这个在Aspire下会很容易下面是所列的步骤:
学习Aspire的基础
为你的等级化数据集创建一个定义文件
在Java代码中调用你得定义文件从而获取ihds
下面对每一步进行详细的介绍
阅读Aspire JAR的用法基础
Aspire 是一个小的JAR 文件它可以直接运行 特别的它可以被一个应用程序服务器调用例如TomcatAspire的核心是一套配置文件 在这些文件中你可以通过Java类术语和这些类的参数声明数据访问机制Aspire 将运行那些Java类并且返回结果对象等级化数据集并非例外
OReilly的一篇早期文章介绍了Aspire:对于Tomcat的开发者来说 Aspire可以作为JAR它会通过定义数据库和调用SQL以及存储过程来让你熟悉这些运作就像配置和初始化Aspire一样
为你的等级化数据集创建一个定义文件
下面是一个等级化数据集的简单定义
###################################
# ihdsTest 数据定义:区
###################################
requestihdsTestclassName=lgenDBHashTableFormHandler
requestihdsTestloopNames=works
#区
requestihdsTestworksclass_requestclassName=lgenGenericTableHandler
requestihdsTestworksloopNames=childloop
requestihdsTestworksquery_requestclassName=comaidataRowFileReader
requestihdsTestworksquery_requestfilename=aspire:\\samples
\\poptabletags\\properties\\poptabledata
#区
requestchildloopclass_requestclassname=lgenGenericTableHandler
requestchildloopquery_requestclassname=comaidataRowFileReader
requestchildloopquery_requestfilename=aspire:\\samples\\poptabletags
\\properties\\poptableda