IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  XML | Information Management | Web development  >

使用 Flex 和 DB2 pureXML 开发富客户端程序

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

讨论

样例代码


级别: 中级

王琳霖 (wangllbj@cn.ibm.com), 软件工程师, IBM
李玉明 (ymli@cn.ibm.com), 软件工程师, IBM

2009 年 4 月 02 日

有过Flex开发经验的人都知道,Flex 的很多控件的 dataprovider 属性都是可以直接接收 XML 数据的,而且提供的非常强大的基于 XML 数据的展现功能。DB2 pureXML™技术对 XML 提供全程的,高效的存贮,查询等功能。通过这篇文章我会介绍给读者怎样整合这两项技术,为用户提供一个不但界面绚丽而且非常高效的应用程序。

前言

在文章中,我将使用 Flex 和 DB2 pureXML 技术去开发一个完整的应用程序,模拟公安系统中从现有的人员数据库中 ( 人员数据是以 XML 的形式存储在 DB2 数据库中 ) 查询数据缩小犯罪嫌疑人的范围,并且假设如果数据发生结构性的变化。在使用 XML 作为数据存储和展现形式中所展现出来的强大的适应性,之所以选择公安行业作为该应用的模拟场景是因为公安系统行业的数据有如下特点:

  1. 数据结构复杂,包含的信息元素多样。在民警的办案过程中,任何微小的线索被遗漏,都可能延误破案的时机,甚至误导民警的思路,所以需要应用系统最大程度的把信息提供给用户—办案民警。
  2. 数据结构和数据项变化的频率高。由于政策的变化或新技术的应用,都有可能导致数据和数据结构的变化 ( 使用自描述的 XML 数据可以解决这个问题 )。
  3. 各个数据实体间差异大,比如,有些人有过犯罪记录,那么他就需要有犯罪记录的信息单元,有些人还需要有入狱记录单元,而有些人没有任何的犯罪记录,这些相关项的信息也就没有。我们的应用中必须能无差别的处理这些情况,即,在应用中我们不应分别处理这些情况 ( 使用自描述的 XML 数据可以解决这个问题 )。
  4. 能对现有复杂的数据提供尽可能复杂,灵活的,高效的查询和重组的功能 ( 使用 DB2 pureXML 提供的强大的对 SQL/XQuery 查询功能满足了这个需求 )。

基于以上需求,如果我们使用普通的关系型数据进行建模,有如下缺点:

  1. 任何的数据结构的变化都将导致数据库结构的变化,这些修改对于一个投入使用的应用系统来讲将是毁灭性。
  2. 对不同形式的数据实体 ( 如上第三点所述 ) 需要在程序代码级别去处理这些区别。
  3. 在对数据进行查询时,需要通过复杂的表间关联去查询。




回页首


软件环境要求

  • DB2 V 9.5 或更高
  • Flash Player 9
  • 应用服务器,如 Tomcat5
  • Adobe Flex Builder 3( 可选 )
  • IBM Data Studio 1.2( 可选 )




回页首


为什么选择 Flex?

随着 WEB2.0 概念的迅速流行,用户对富客户端程序 (AIR: rich Internet application) 的兴趣也开始升温,而基于 ActionScript3.0 编程语言的 Adobe Flex 正好迎合这样的需求,因为:

  • Flex 生成 SWF 文件,并且使用 Flash Player 播放,而现在绝大多数浏览器都支持并且安装了 Flash Player。
  • Flex 的提供的开发框架,它提供了可重用可扩展的 UI 组件,服务访问组件,事件处理等技术,让你可以使用我们开发人员非常熟悉的方式 -- 基于代码的方式去开发 Flash 应用。
  • 使用 Flex, 您可以随意的设计和实现以用户感受为核心的用户界面,而不用担心浏览器的兼容问题。
  • Flex 提供了很多的基于 XML 标准的类,这些类提供了强大的,易用的功能和 XML 数据协同工作。




回页首


DB2 pureXML 技术特点

  • DB2 pureXML 的数据类型和存储技术可以高效的管理具有层次结构的 XML 文档。
  • DB2 pureXML 索引技术提高了在 XML 文档子集中的搜索速度。
  • 提供了对新的,基于行业标准的查询语言的支持 (XQuery 和 SQL/XML) 和新的查询优化技术。
  • 提供了对 XML 模式进行管理,验证的支持。




回页首


为什么是 DB2 pureXML 和 Flex 整合

通过前面的介绍我们能够知道公安系统数据的特点,Flex 的技术特点,DB2 pureXML 的技术特点。我想大家已经能够想到了,如果能够使用 XML 作为数据的存储形式,而又可以有一个和 XML 数据能够无缝结合,易于开发,界面友好的用户界面设计和开发工具把这些数据展现到用户面前。在这两者之间再有一个能够提供高效,易用的对 XML 数据进行查询,重组存储工具,那这样复杂的问题好像已经迎刃而解了。你的想法是正确的,下面我将用这个小的应用程序去模拟这些实际问题。下图是应用程序的整体框架图:


图 1. 整体框架图
整体框架图

使用 XML 格式的数据可以简化系统构架复杂程度。在开发此类基于 XML 的应用系统开发中,我们需要投入大量精力在 XML 数据格式的设计上。在如上的框架图中,我们使用 XML 数据做为请求数据和结果数据的传输形式。在设计的开始我们就应该设计出一个规则,让前端客户端知道哪些数据不应该被显示,哪些数据应该被显示,应该怎样显示,显示什么。在这里我们只是简单的把标签名字最为显示信息,读者可以任意指定他的显示信息在应用中的数据中 ( 数据格式请参考”数据模型”部分 ), 节点中有两个属性 : visible, label 分别用来表示这个节点数据是不是应该被显示,这个节点数据应该显示什么。依照这个规则,只要后台提供的数据满足这个规则,在数据结构发生任何变化,客户端不需要去修改而自动的适应这些变化。

  • 后台数据中添加这些属性: do insert attribute label {$new/ 人员 / 姓名 /fn:local-name(.)} into $new/ 人员 / 姓名。
  • 在 UI 部分指定显示这些属性信息:<mx:Tree labelField="@label" />。

可以看出通过制定上述的规则,DB2 pureXML 和 Flex 可以实现无缝连接。比如在本应用中模拟的客户需求的变化,需要在原来结果的基础上增加监狱信息,后台的存储过程增加这部分数据的时候让它符合这个规则,前端的 UI 部分就会自动的把数据展现出来。





回页首


Flex 支持 XML 数据控件介绍

在 Adobe Flex 的很多控件都是遵从 XML 数据规范,这些控件中提供了很多直接的功能和方法,这些功能和方法为您提供了强大的,易用的功能和 XML 数据协同工作功能。


图 2. 控件示例
控件示例

Tree 控件就是一个典型的例子,Tree 从 data provider 中读取数据,定义这个 tree 的展现形式并且把相关的数据展现到相应的节点上。

Tree 控件中有许多高级的特性被支持,如果您感兴趣可以参考 Adobe Flex 官方的 Language Reference。在这里就只介绍 Tree 控件和 Tree 控件的父类的几个属性和方法以便能够更好的理解文章中的代码。

  • dataProvider, 将在 Tree 控件上被展现的数据集。
  • labelFunction, 用户自定义的 function, function 会在显示每个节点之前调用这个 function, 调用 function 中的逻辑展现节点信息。
  • labelField, 指定把 data provider 中的哪个数据域的数据显示节点上。
  • dataDescriptor, Tree 控件使用这个 Class 去分析并且处理数据源的数据。这个 Class 必须是实现 IDataDescriptor 接口。




回页首


开发 UI 部分

  • 新建一个叫 main 的 Flex Application。
  • 在 Flex 应用中,为了访问后台提供的服务,我们添加一个 HttpService 控件,下面给出了在本应用中使用的到的这个空间的属性的简单解释说明,如果您想更详细的学习请参考相关的 API 文档。
    • 添加 ID 属性,这个属性为了在其他控件需要调用它去访问后台服务的使用。
    • 设置 url 属性,这个属性的属性值需要被指定为我们后面要提到的暴露的 web service 的完整的 url 地址 (http://localhost:8088/Flex3DemoWebServiceFlex/rest/WebServiceFlex/GETRESULT)。 注意 : 这个 URL 必须和你本地部署的应用的 URL 相一致。
    • Method 属性被设置为 post 方式。
    • resultFormat 被设置为 e4x, XML 格式的数据遵循这个标准。
    • myHttpService.addEventListener(ResultEvent.RESULT,renderResult)。这里指定的回调函数” renderResult ”,就是在服务器返回结果后调用的函数,我们在函数中只是简单的把返回的结果赋值给展现结果的 Tree(id=resultTree) 控件。
  • 在 application 中添加 Tree 控件,id 为 queryTree, 并且直接为这个 Tree 控件的 dataProvider 属性绑定一个 XMLListCollection。

    清单 1. 示例代码
    
    <mx:Tree 
     id="tree" 
     width="100%" height="100%"  
     labelFunction="treeRender" 
     dataDescriptor="{new PredTreeDescriptor()}" 
     showRoot="true"  
     editable="true" 
     editorHeightOffset="40" editorWidthOffset="-100" 
     editorXOffset="0" editorYOffset="20" 
     itemEditBeginning="disableEditing(event);" 
     itemEditBegin="getConditionEditor(event)" 
     itemEditEnd="updateConditionTree(event);" 
     cornerRadius="3" 
     alpha="1.0"><mx:XMLListCollection id="searchCondition"> 
    	 <mx:XMLList> 
    		 < 查询条件 label=" 查询条件 "> 
    			 < 姓名 label=" 姓名 " op="=, 包含,"/> 
    			 < 姓名全拼 label=" 姓名全拼 " op="=,"/> 
    			 < 民族 label=" 民族 " op="=,"/> 
    			 < 出生日期 label=" 出生日期 " op="=, 大于,小于,"/> 
    			 < 住址 label=" 住址 " op="=, 包含,"/> 
    			 < 特征 label=" 特征 "> 
    				 < 口音 label=" 口音 " op="=,"/> 
    				 < 绰号 label=" 绰号 " op="=, 包含,"/> 
    				 < 纹身 label=" 纹身 " op="="/> 
    			 </ 特征 > 
    			 < 案件 label=" 案件 "> 
    				 < 描述 label=" 描述 " op=" 包含,"/> 
    				 < 时间 label=" 案件发生时间 " op="=, 大于,小于,"/> 
    			 </ 案件 > 
    		 </ 查询条件 > 
    	 </mx:XMLList> 
     </mx:XMLListCollection></mx:Tree>
    
    

    在 labelFunction 中我们指定了个一个 function “ renderTree ”,在这个 function 中,curValue 和 curOp 是在 runtime 的时候通过如下图的编辑窗口,用户输入的查询条件的值和操作,之后 function 把原有的 label 值这两个新加的属性拼加起来作为这个节点的 label 的值。例如图中的”姓名”节点。这个查询的 XML 文档格式和后台数据库中存储的数据的个很相似,在这里只是增加了一个和查询相关的属性,这样可以让用户组合任何复杂的查询条件。

    • labelFunction 被指定为一个自定义的 function:renderTree, 这个 function 用来处理 label 值。通过定义这个 fucntion, 我们就可以在用户输入查询条件后动态的把它显示到界面上。

      清单 2. renderTree()
      
      private function renderTree(item:Object):Object{ 
      	 var node:XML = XML(item); 
      	 var display:String=""+node.attribute('label'); 
      	 if(display=='') 
      		 display=node.name(); 
      	 var curValue:String=" "+node.attribute('curValue'); 
      	 if(curValue==' ') 
      		 return display; 
      	 var curOp:String=" "+node.attribute('curOp'); 
      	 if(curOp==' ') 
      		 curOp=' ='; 
      	 return display+curOp+curValue; 
       }

    • dataDescriptor 被指定为一个实现了 ITreeDescriptor 接口的实现类 MyTreeDescriptor。在这个 Class 中的一个最主要的一个方法 getChildren, 在这里去实现我们自己的逻辑,决定 dataProvider 的数据源中的节点,有哪些属性的节点被显示,哪些不显示,哪些可以特殊显示,等等。

      清单 3. getChildren()
      
      public function getChildren(node:Object,model:Object):ICollectionView{ 
      	 if(node is XML){ 
      		 var col:XMLListCollection = new XMLListCollection(); 
      		 col.filterFunction=function(item:Object):Boolean{ 
      		 var visibility:XMLList=XML(item).attribute('visible'); 
      		 if(visibility.length()!=0&&visibility[0]=='false') 
      			 return false; 
      		 else 
      			 return true; 
      		 } 
      		 col.source=XML(node).children(); 
      		 return col; 
      	 } 
      	 return null; 
       }

    • 其他的一些属性都是用来指定编辑窗口的属性,如果有兴趣可以参考文档附带的源码。
  • 在 application 中再添加一个 Tree 控件,id 为 resultTree, 展现查询到的结果。

    图 3. 查询条件录入框
    查询条件录入框





回页首


DB2 存储过程

本应用中将使用存储过程去实现对数据处理和逻辑的控制。所以,我将首先介绍一下 DB2 的存储过程的相关背景知识和在本应用中使用存储过程所带来的优势。

  • 简要介绍

    存储过程可以被用来封装多条 SQL 语句,这些语句之间可以加入符合一定业务逻辑控制条件,所以存储过程可以被看作是应用逻辑的一部分,作为数据库应用对象 -- 存储过程 (Stored procedure), 用户定义方法 (User-defined Function), 触发器 (Trigger) 统称为数据库应用对象 (database application objects)-- 运行在数据库服务器端。使用数据库应用对象能够显著提高应用系统的运行时的效率,并且,可以充分使用服务器端的 CPU 和磁盘空间,尽量减少对各种终端的性能的依赖。

  • 优势
    • 易于管理。数据库应用对象可以被模型化,所以可以从一个数据库移植到其他的数据库上使用。
    • 是 DBA 和应用程序开发者之间的角色界限更明确。DBA 对数据模型更清楚,而应用系统开发人员对系统的接口更清楚。复杂的业务逻辑被封装在数据库应用对象中,对于应用系统开发人员只需要知道调用哪个存储过程或方法去满足自己的业务需要。
    • 提高效率。把业务逻辑封装在运行在服务器端的数据库应用对象中,比如,存储过程,将会提高应用的运行效率,特别是数据驱动的应用,就像本文中实现的这个应用程序。

综上所述的优势,可以总结出在本应用中是用存储过程的优势如下:

  • 存储过程支持所有 pureXML 提供的关于 XQuery 方法。
  • 一致性上,在本应用中,后台的数据处理部分,可以无缝的使用和前端 UI 部分一样的数据模型,简化了逻辑处理,提高了处理效率。
  • 使用存储过程实现部分业务逻辑控制,可以减少客户端和服务器端的数据传输量。




回页首


开发后台数据服务部分

虽然 Flex 的 Tree 控件可以把 XML 的数据非常直观的展现到用户面前,但是 Tree 控件同样需要一个有着一定数据格式的 XML 数据,因为如果直接使用并展示后台的原始数据,将会给应用的可适应性大大折扣。同时 Flex 没有提供强大的数据查询的功能。这就需要在 Flex 和后台数据库之间有一个支持对数据能够进行高效查询,和对结果数据进行重组,增加特殊属性和节点的功能层,这里我们将使用存储过程去实现这个功能层。以下是对存储过程的说明。

后台数据查询功能开发,使用的 IBM Data Studio, 使用 IBM Data Studio 新建一个叫 FlexDemo 的 ”Data Development Project ”。在工程中 IBM Data Studio 会提供很多非常的 assistant 加快和简化我们的开发效率和流程,关于如何使用 IBM Data Studio,可以参考 ”使用 IBM Data Studio 开发数据工程” 部分。我们在这个工程中新建一个叫 getResult 的存储过程,我们只需要使用这个存储过程就可以实现应用的需求:接受 XML 格式的查询条件,解析查询条件,查询数据,重新组织查询结果的源数据组装成我们需要的任何形式的 XML 数据。最后我们在使用 IBM Data Studio 的 Web Service 定义发布功能发布一个 Web Service。 而把这个存储过程发布成一个 Web Service,你只需要做的就是拖拽,点击等一系列简单的操作。

  • 解析 XML 格式的查询条件,使用这条语句,我们把查询条件中的条件和操作都赋值到相应的本地变量中去。这样我们可以方便的判断哪个属性是否被作为了查询条件,避免每次使用这些查询条件时都去解析 XML 数据。

    清单 4. 解析查询条件
    
    SELECT t.* INTO 
    	 v_name,v_nameop 
    	,v_pinyin,v_pinyinop 
    	,v_nation,v_nationop 
    	……
     FROM XMLTABLE 
     ( 
    	 '$d/ 查询条件 ' 
    	 PASSING inQueryXML as "d" 
    	 COLUMNS 
    	 name      VARCHAR(128)      PATH ' 姓名 /@curValue' 
    	,nameop   VARCHAR(128)      PATH ' 姓名 /@curOp' 
    	,pinyin      VARCHAR(128)      PATH ' 姓名全拼 /@curValue' 
    	,pinyinop   VARCHAR(128)      PATH ' 姓名全拼 /@curOp' 
    	,nation      VARCHAR(128)      PATH ' 民族 /@curValue' 
    	,nationop   VARCHAR(128)      PATH ' 民族 /@curOp' 
    	…………
     ) as t;
    

    拼接一个动态的查询字符串并且把它赋予一个本地变量 v_stmt_text, 之后定义的一个 statement, 使用这个查询字符串去查询数据,如下是这个动态字符串的完整格式。



    清单 5. 解析查询条件
    						
    SET ? = XMLQUERY 
    ( 
    ' 
    < 结果集 > 
    { 
    for $i in db2-fn:xmlcolumn(''FLEXSCHEMA.FLEXDEMO.DOC'') 
     let $id := $i/ 人员 /ID 
     where $i/ 人员 [1 
    	 --optional conditions 
    	 -- one of this two 
    	 and fn:contains( 姓名,$name) 
    	 and 姓名 = $name 
    	
    	 and 姓名全拼 = $pinyin 
    	 and 民族 = $nation 
    	
    	 --one of this three 
    	 and 出生日期 > $birthday 
    	 and 出生日期 < $birthday 
    	 and 出生日期 = $birthday 
    	
    	 -- one of this two 
    	 and fn:contains( 住址,$address) 
    	 and 住址 = $address 
    	 ] 
    	 and $i/ 人员 / 特征 [1 
    	 and 口音 = $accent 
    	
    	 -- one of this two 
    	 and fn:contains( 绰号,$nickname) 
    	 and 绰号 = $nickname 
    	
    	 and 纹身 = $tattoo 
    	 ] 
    	 and $i/ 人员 / 案件 [1 
    	 and fn:contains( 案件描述,$desc) 
    	
    	 -- one of this three 
    	 and 时间 > $casetime 
    	 and 时间 < $casetime 
    	 and 时间 = $casetime 
    	 ] 
    return ( 
    copy $new:=$i 
     modify ( 
     do insert attribute label {$new/人员/fn:local-name(.)} into $new/人员
    ,do insert attribute visible {"false"} into $new/人员/ID 
    ,do insert attribute label {$new/人员/姓名/fn:local-name(.)} into $new/人员/姓名
    ,do insert attribute visible {"false"} into $new/人员/姓名全拼
    ,do insert attribute label {$new/人员/身份证/fn:local-name(.)} into $new/人员/身份证
    ,do insert attribute label {$new/人员/民族/fn:local-name(.)} into $new/人员/民族
    ,do insert attribute label {$new/人员/出生日期/fn:local-name(.)} into $new/人员/出生日期
    ,do insert attribute visible {"false"} into $new/人员/照片
    
    ,do insert attribute label {$new/人员/住址/fn:local-name(.)} into $new/人员/住址
    
    ,do insert attribute label {$new/人员/特征/fn:local-name(.)} into $new/人员/特征
    ,do insert attribute label {$new/人员/特征/口音/fn:local-name(.)} into $new/人员/特征/口音
    ,do insert attribute label {$new/人员/特征/绰号/fn:local-name(.)} into $new/人员/特征/绰号
    ,do insert attribute label {$new/人员/特征/纹身/fn:local-name(.)} into $new/人员/特征/纹身
    
    ,do insert attribute label {$new/人员/案件/fn:local-name(.)} into $new/人员/案件
    ,do insert attribute label {$new/人员/案件/案件描述/fn:local-name(.)} into $new/人员/案件/案件描述
    ,do insert attribute label {$new/人员/案件/地点/fn:local-name(.)} into $new/人员/案件/地点
    ,do insert attribute label {$new/人员/案件/时间/fn:local-name(.)} into $new/人员/案件/时间
    ,do insert attribute visible {"false"} into $new/人员/案件/涉案其他人员
     ) 
    return $new 
    
    ) 
    } 
    </ 结果集 >' 
    passing 
    CAST(? AS VARCHAR(128)) AS "name" 
    	,CAST(? AS VARCHAR(128)) AS "pinyin" 
    	,CAST(? AS VARCHAR(128)) AS "nation" 
    	,CAST(? AS VARCHAR(128)) AS "birthday" 
    	,CAST(? AS VARCHAR(128)) AS "address" 
    	,CAST(? AS VARCHAR(128)) AS "accent" 
    	,CAST(? AS VARCHAR(128)) AS "nickname" 
    	,CAST(? AS VARCHAR(128)) AS "tattoo" 
    	,CAST(? AS VARCHAR(128)) AS "desc" 
    	,CAST(? AS VARCHAR(128)) AS "casetime" 
    )

  • 在源数据的基础上重新组织数据,添加一些在 Flex 的前端 UI 中需要用的,用户显示的属性。

    清单 6. 数据重构
    						
    do insert attribute label {$new/ 人员 /fn:local-name(.)} into $new/ 人员
    ,do insert attribute visible {"false"} into $new/ 人员 /ID 
    ,do insert attribute label {$new/ 人员 / 姓名 /fn:local-name(.)} into $new/ 人员 / 姓名
    ,do insert attribute visible {"false"} into $new/ 人员 / 姓名全拼

  • 为 STATEMENT 变量传入参数,执行上面的动态的查询语句

    清单 7. 传入参数
    						
    PREPARE s_stmt FROM v_stmt_text; 
     EXECUTE s_stmt INTO outResultXML USING 
     v_name,v_pinyin,v_nation,v_birthday,v_address, 
     v_accent,v_nikename,v_tattoo,v_desc,v_casetime;
    
    





回页首


业务需求发生变化

现在假设公安系统和监狱系统的数据需要整合去显示更为详细的人员信息,监狱系统提供了新的数据库表,在这表中有 ID 和我们原来的人员表中的人员 ID 对应,并且数据也是使用 XML 作为存储形式。为了满足这个需求,我们需要在原来的查询结果的基础上,通过这个外键的关联再到监狱表中把需要的数据查询出来,并且追加到现有的结果后面。为适应这个变化,对于使用 DB2 pureXML 的数据库技术和 Flex 的 data driver 控件结合的应用,是非常简单的。我们现在只需要简单修改存储过程,添加如下的语句到上面给出的完整的 XQuery 语句的 modify 子句的最后。


清单 8. 增加数据
				
,do insert copy $prison := db2-fn:xmlcolumn('FLEXSCHEMA.PRISONINFO.DOC')/ 监狱 [ID=$id] 
modify( 
	 do insert attribute label {$prison/fn:local-name(.)} into $prison 
	,do insert attribute visible {"false"} into $prison/ID 
	,do insert attribute label {$prison/ 名称 /fn:local-name(.)} into $prison/ 名称
	,do insert attribute label {$prison/ 服刑期限 /fn:local-name(.)} into $prison/ 服刑期限
	,do insert attribute label {$prison/ 入狱原因 /fn:local-name(.)} into $prison/ 入狱原因
	,do insert attribute label {$prison/ 表现 /fn:local-name(.)} into $prison/ 表现
 ) 
return $prison 
 as last into $new/ 人员

重新部署我们的存储过程,在结果中就可以看到我们新增加的数据了。而在这里 XQUERY 多数语句都是为数据添加额外的属性为 Flex 的 Tree 提供显示控制。如果我们只是想把监狱的数据 append 到原数据后面,只需要增加一条语句 :do insert db2-fn:xmlcolumn('FLEXSCHEMA.PRISONINFO.DOC')/ 监狱 [ID=$id] as last into $new/ 人员 就可以了,所以我们可以发现,使用这样的构架去开发一个应用系统,对于后期由于需求变化而产生的维护量是非常小的!这里我们也可以修改 UI 部分的 XML 查询数据个格式,让用户有机会输入监狱的相关信息做为查询条件的一部分,而后台的部分也可以增加相应的处理子句适应查询变化。有兴趣的读者可以根据现有代码自行修改存储过程 。





回页首


数据模型


清单 9. 人员数据
				
< 人员 > 
	 <ID>2</ID> 
	 < 姓名 > 张薇 </ 姓名 > 
	 < 姓名全拼 >zhangw</ 姓名全拼 > 
	 < 身份证 >22036955874425850</ 身份证 > 
	 < 民族 > 羌 </ 民族 > 
	 < 出生日期 >20001325</ 出生日期 > 
	 < 照片 >a.jpg</ 照片 > 
	 < 住址 > 北京,北京,门头沟,门头沟大街 26 号,110043</ 住址 > 
	 < 特征 > 
		 < 口音 > 河南 </ 口音 > 
		 < 绰号 > 六哥 </ 绰号 > 
		 < 纹身 > 海盗 </ 纹身 > 
	 </ 特征 > 
	 < 案件 > 
		 < 案件描述 > 参与了一场在秀水街头的斗殴事件 ( 一人受刀伤 )。 
后被假释,因为不能证明那个伤人者就是他,控告也被撤销 </ 案件描述 > 
		 < 地点 > 秀水街 </ 地点 > 
		 < 时间 >2008-12-09T18:23:52.078</ 时间 > 
		 < 涉案其他人员 >1</ 涉案其他人员 > 
	 </ 案件 > 
 </ 人员 >


清单 10. 监狱数据
				<?xml version="1.0"?> 
 < 监狱 > 
	 <ID>1</ID> 
	 < 名称 > 怀柔监狱 </ 名称 > 
	 < 服刑期限 >20 年 </ 服刑期限 > 
	 < 入狱原因 > 偷窃 </ 入狱原因 > 
	 < 表现 > 表现良好,提前释放 </ 表现 > 
 </ 监狱 >


清单 11. 查询结果数据 1
				
<?xml version="1.0"?> 
	 < 人员 label=" 人员 "> 
	 <ID visible="false">1</ID> 
	 < 姓名 label=" 姓名 "> 赵继海 </ 姓名 > 
	 < 姓名全拼 visible="false">zhaojihai</ 姓名全拼 > 
	 < 身份证 label=" 身份证 ">22036955874425834</ 身份证 > 
	 < 民族 label=" 民族 "> 汉 </ 民族 > 
	 < 出生日期 label=" 出生日期 ">19981223</ 出生日期 > 
	 < 照片 visible="false">a.jpg</ 照片 > 
	 < 住址 label=" 住址 "> 北京,北京,西城,长安街 25 号,110043</ 住址 > 
	 < 特征 label=" 特征 "> 
		 < 口音 label=" 口音 "> 东北 </ 口音 > 
		 < 绰号 label=" 绰号 "> 大鲨鱼 </ 绰号 > 
		 < 纹身 label=" 纹身 "> 骷髅头 </ 纹身 > 
	 </ 特征 > 
	 < 案件 label=" 案件 "> 
		 < 案件描述 label=" 案件描述 "> 参与了一场在秀水街头的斗殴事件 ( 一人受刀伤 )。 
后被假释,因为不能证明那个伤人者就是他,控告也被撤销 </ 案件描述 > 
		 < 地点 label=" 地点 "> 秀水街 </ 地点 > 
		 < 时间 label=" 时间 ">2008-12-09T18:23:52.078</ 时间 > 
		 < 涉案其他人员 visible="false">1</ 涉案其他人员 > 
	 </ 案件 > 
 </ 人员 >


清单 12. 查询结果数据 2
				
<?xml version="1.0"?> 
 < 人员 label=" 人员 "> 
	 <ID visible="false">1</ID> 
	 < 姓名 label=" 姓名 "> 赵继海 </ 姓名 > 
	 < 姓名全拼 visible="false">zhaojihai</ 姓名全拼 > 
	 < 身份证 label=" 身份证 ">22036955874425834</ 身份证 > 
	 < 民族 label=" 民族 "> 汉 </ 民族 > 
	 < 出生日期 label=" 出生日期 ">19981223</ 出生日期 > 
	 < 照片 visible="false">a.jpg</ 照片 > 
	 < 住址 label=" 住址 "> 北京,北京,西城,长安街 25 号,110043</ 住址 > 
	 < 特征 label=" 特征 "> 
		 < 口音 label=" 口音 "> 东北 </ 口音 > 
		 < 绰号 label=" 绰号 "> 大鲨鱼 </ 绰号 > 
		 < 纹身 label=" 纹身 "> 骷髅头 </ 纹身 > 
	 </ 特征 > 
	 < 案件 label=" 案件 "> 
		 < 案件描述 label=" 案件描述 "> 参与了一场在秀水街头的斗殴事件 ( 一人受刀伤 )。 
后被假释,因为不能证明那个伤人者就是他,控告也被撤销 </ 案件描述 > 
		 < 地点 label=" 地点 "> 秀水街 </ 地点 > 
		 < 时间 label=" 时间 ">2008-12-09T18:23:52.078</ 时间 > 
		 < 涉案其他人员 visible="false">1</ 涉案其他人员 > 
	 </ 案件 > 
	 < 监狱 label=" 监狱 "> 
		 <ID visible="false">1</ID> 
		 < 名称 label=" 名称 "> 怀柔监狱 </ 名称 > 
		 < 服刑期限 label=" 服刑期限 ">20 年 </ 服刑期限 > 
		 < 入狱原因 label=" 入狱原因 "> 偷窃 </ 入狱原因 > 
		 < 表现 label=" 表现 "> 表现良好,提前释放 </ 表现 > 
	 </ 监狱 > 
 </ 人员 >





回页首


使用 IBM Data Studio 开发数据工程

在开发应用过程中,使用 IBM Data Studio 提供的很多非常实用的功能可以减少很多工作量。比如,SQL/XQuery 的语法验证,存储过程的运行和调试,SQL 命令编辑器,数据库浏览器,Web Service 的自动配置,生成,运行等等。

如下简单介绍一下使用 DS 开发一个 Data Development Project 的流程。





回页首


总结

在 WEB2.0 风靡世界的今天,基于 B/S 模式的富客户端程序越来越成为产品用户的新宠。而系统的可维护性和可适应性一直是软件工程学一直探讨的问题。而现在 Adobe Flex 和 IBM DB2 pureXML 技术分别相应的解决了以上的问题,所以以上两项技术的结合使用就可以更充分的发挥他们的作用。并且 Adobe Flex Build 3 和 IBM Data Studio 又为他们的开发提供了非常友好,功能非常强大开发平台,可以初学者很快熟练运用它们,提高工作效率。






回页首


下载

名字大小下载方法
source.zip10KBHTTP
关于下载方法的信息

注意:

  1. 本文中使用的源码,二进制文件和安装向导!


参考资料

学习

获得产品和技术
  • 下载IBM 软件试用版,体验强大的 DB2®,Lotus®,Rational®,Tivoli®和 WebSphere®软件。

讨论


作者简介

王琳霖是 IBM 中国软件开发中心的软件工程师。


李玉明是 IBM 中国软件开发中心的软件工程师。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款