技术开发 频道

基于Jazz技术构建企业级Web2.0应用(1)

【IT168 专稿】

    Jazz技术平台是一个可伸缩、可扩展的团队协作平台,用于无缝地集成整个软件生命周期中的任务。同时Jazz技术平台也为Web2.0应用程序的开发和扩展提供了有用的框架,开发人员可以很容易地利用它开发出基于Ajax和REST编程模型的Web2.0应用。在REST服务端,Jazz提供一个REST服务框架,此框架抽象了处理REST请求的细节(HTTP、数据封装和解封等)。REST服务通过Java接口进行定义,该Java接口和相应的基于EMF的存储模型在运行时用于对请求和响应进行封送处理。在Web UI端,Jazz基于开放源代码的Dojo Toolkit,提供一个Jazz Ajax Framework(JAF),从而简化了Ajax开发。

    本系列文章首先概述Jazz平台技术架构和编程模型,然后以开发人员熟悉的PetStore为例,详细阐述使用Jazz技术开发企业级Web2.0应用的全过程。其中PetStore与Jazz技术平台间的依赖关系如图1所示。


    图 1. PetStore与Jazz平台依赖关系

    通过阅读本系列文章,您将获得以下帮助:

    · 了解Jazz技术架构和编程模型。理解如何利用Jazz技术进行应用组件开发

    · 了解如何通过Jazz提供的基于EMF建模的O-R Mapping机制实现数据模型持久化

    · 了解如果通过Jazz提供的Process构件来完成业务流程的管理和定制

    · 了解如何通过Jazz提供的Ajax框架(JAF),开发出基于Ajax和REST编程模型的Web2.0应用

    本文是该系列的第一部分,将介绍Jazz平台的技术架构和编程模型,并完成PetStore示例应用开发的第一步——数据模型设计与实现。

    Jazz技术概览

    技术架构

    Jazz具有模块化、可扩展的体系结构。Jazz采用Eclipse插件体系,开发者可以通过提供Eclipse bundle对Jazz功能的进行扩展。围绕某一功能而开发的若干个bundle被组织到一个Jazz构件中,目前Jazz的构件如图2所示


    图 2. Jazz Platform

    图中的每个构件实现一定的功能。其中Repository和Team Process是必须的,它们构成Jazz的内核。其中Repository负责对数据进行处理、完成O-R 映射和数据持久化等,是所有数据驱动型应用必须依赖的组件。目前Repository组件提供了对Oracle、DB2和Derby等主流数据库的操作,它通过IRepositoryItemService和IQueryService提供上层API来对数据的增、删、改、查进行统一封装,然后在根据用户的数据库选择和配置信息,翻译成具体数据库厂商支持的SQL再调用底层的JDBC来实现对具体DBMS的操作。从而屏蔽了不同数据库厂商对SQL标准实现不同的问题,为上层应用在不同数据库上的移植提供了解决方案。在本系列文章的第二部分有对Repository组件的详细介绍和使用。Process组件负责Jazz的业务流程管理,它为应用程序提供了AOP的底层支持。在本系列文章的第三部分有对Process组件的详细介绍。这两个核心构件不依赖任何其它构件,因而可以被任何其它构件所依赖。

    编程模型

    基于Jazz平台的开发和与基于众多主流的J2EE框架开发类似,都采用MVC的分层模型。值得一提的是Jazz提供了各种不同形式的服务,如Restful服务、RPC服务和Http RAW服务,因此它为不同种类的客户端接入提供了相对统一的基于service的接口,无论是基于Ajax的Web UI还是基于RCP的Eclipse UI都可以统一的使用同一套后端提供的服务,无需做任何修改,它为不同类型的UI接入提供了内在的支持。其模型如下图3所示:


    图 3. Jazz Framework

    在一个典型的Web应用中,一个Jazz构件可能包含的bundle包括:

    · Common bundle:用于数据模型和服务接口的定义,类似于MVC的Model层

    · Service bundle:用于服务的实现,类似于MVC的Controller层

    · Web UI bundle:用于用户界面的实现,类似于MVC的View层

    因此Jazz把一个典型的Web开发转化成了Eclipse插件的开发,应用程序通过对不同扩展点进行扩展实现相应的功能并具有很强的重用性和可扩展性。一个Jazz构件可以依赖其它Jazz构件,并调用被依赖构件提供的服务。而应用程序只需要关注对不同服务的调用,服务的实例化和维护由Jazz平台进行提供,简化应用程序开发,体现了控制反转(Inverse Of Control)的思想。有一点需要注意:Jazz构件之间的依赖关系是单向的,不能形成直接或间接的循环依赖(即不能出现A依赖B,B依赖A;或A依赖B,B依赖C,C依赖A)。

    PetStore设计概览

    PetStore示范应用是一个基于Web的电子商务应用系统,它将实现以下几个主要用例:查询宠物、购买宠物、发布宠物、查看交易记录。用例如图4所示


    图 4. PetStore用例图

    用户能够通过PetStore平台编辑宠物的相关信息,发布自己欲出售的宠物;可以通过分类的方式浏览别人出售的宠物,搜索宠物信息等;对自己感兴趣的宠物可以进行购买,并查询自己的历史交易记录。

    在Jazz PetStore示范应用中,我们使用一个Jazz构件PetStore实现其功能。其中包含三个plug-in项目:

    · com.ibm.petstore.common 存放数据模型和服务接口申明

    · com.ibm.petstore.service 实现服务接口

    · com.ibm.petstore.web 实现基于JAF的胖客户端UI

    下面我们将以PetStore的模型层设计为例,介绍基于Jazz的数据持久化过程。

    数据持久化

    Jazz平台提供了一个基于EMF的O-R mapping框架,能够帮助开发人员以EMF建模的形式完成数据库建模和数据持久化工作。开发人员只需根据业务的需要设计自己的实体对象POJO(Plain Old Java Object)以及POJO之间的关系,并在EMF的Ecore模型中为实体对象提供基于Jazz的元数据信息,Jazz的Repository工具会根据建立的Ecore模型自动生成相应的POJO,并把这些POJO映射到数据库的表结构中。从而实现了Ecore模型->POJO->数据库持久化的目标,因此Jazz的储存模型可以被视为一种有着Jazz特殊格式的Ecore模型。

    在Jazz中所有的持久化数据都被存储在repository中,每个持久化数据都被称为条目(item),每个条目都含有自己的itemId和stateId。Jazz包含两种不同的数据类型: SimpleItem和Auditable。它们是其它持久化数据类型的超类。SimpleItem用于那些不需要记录历史情况的简单数据,Auditable则记录了数据的历史情况,每次对数据条目的修改都将产生一个新的stateId,所不同的是对于SimpleItem仅仅保留最新的stateId而不保存之前的记录。Auditable的数据不仅保存新的stateId还会把之前每次修改的数据保存起来,每个数据版本都与一个stateId对应,并且可以通过数据的itemId取到这个数据每个版本的历史记录。

    在我们示范应用中,我们将建立Category、Product、Seller三个POJO来存储持久化数据。其中Category用来描述宠物的种类信息,Seller用来描述卖家信息,Product用来描述宠物,每个宠物都一个种类和一个出售者。为了简单起见,我们不需要保留数据的历史记录,所以采用了SimpleItem作为它们的超类。它们之间的关系如图5所示,注意:Content是Jazz里的内建数据类型,被用来保存图片信息。


    图 5. PetStore数据模型

    完成了PetStore的数据模型的设计后,下面我们将详细介绍如何基于Jazz提供的O-R mapping功能完成数据模型持久化的过程。

    创建common bundle

    下面我们将完成PetStore开发的第一步:创建com.ibm.com.petstore.common bundle并完成PetStore数据模型的开发。创建插件项目,如图6所示。


    图 6. 创建插件项目

    指定项目名称(com.ibm.petstore.common),使用缺省的location,目标环境设置为OSGi framework:equinox,如图7所示。


    图 7. 指定项目名称


    图 8. 设置插件特征

    设置插件特性,这里使用缺省值,如果不需要activator就取消勾选框,如图8所示。


    图 9. 设置插件模板

    不使用模板,点击“Finish”完成插件项目的创建。

    设置插件依赖

    在plug-in manifest editor中添加以下的插件依赖项,如图10所示。

    · org.eclipse.core.runtime

    · org.eclipse.emf.ecore

    · org.eclipse.emf.ecore.sdo

    · com.ibm.team.repository.common


    图 10. 设置插件依赖

    在plug-in的根目录下创建一个名为src-gen的Source Folder,用于将来存放由Ecore模型自动生成的代码。

    定义模型

    New->Source Folder取名为src-gen在plug-in根目录下同时创建一个名为models的子目录(如图11所示), 然后在其中创建一个新的EMF ecore模型。New->Other...->Example EMF Model Creation Wizards->Ecore Model给模型取名为petstore.ecore,其余选项保持默认值即可。


    图 11. 设置生成代码的目录

    现在打开这个模型,你将看到一个树形结构的Ecore模型编辑器。首先你需要把Jazz提供的repository.ecore加入到petstore Ecore模型的资源引用中,右键点击编辑器里的任意节点,在上下文菜单中选择Load Resource...在选择资源的对话框里填入如下的URI,这个 URI代表repository.ecore在你的目标平台中的位置platform:/plugin/com.ibm.team.repository.common/models/repository.ecore

    注意:如果你的目标平台没有找到repository.ecore,你需要手动的把com.ibm.team.repository.common插件手动import到你的workspace中。

    然后点击OK按钮.这时你将看到repository.ecore被成功的引入到Ecore编辑器中。然后选择EPackage节点(初始时是null),点击右键并选择Show Properties View。你将通过属性编辑窗口来编辑每个节点的属性. 我们首先为EPackage节点设置如下属性值,如图12所示。


    图 12. EPackage节点属性

    在EPackage节点下添加EAnnotation子节点 (右键点击PetStore EPackage然后选择New Child->EAnnotation),并给它设置如下的source和详细的keys 和values:

EAnnotation
Source
teamModel
Details Entry
Key
clientProject
Value
com.ibm.petstore.common
Details Entry
Key
clientSrcFolder
Value
src-gen
 
 
 
 
 
 
 
 
 
 

    clientProject设为com.ibm.petstore.common表示将来存放生成代码的project,clientSrcFolder表示自动生成代码放入的源代码目录,这里选择之前建好的src-gen中,目的是把自动生成的代码分隔开进行管理。

    现在在根EPackage下添加一个名为petstore的子EPackage,并设置如下的属性值:


    图 13. EPackage节点属性

    注意:Ns URI的值必须与组件名一致,所以这里必须是com.ibm.petstore

    在这个EPackage下添加一个名为teamPackage的EAnnotation,并给它设置如下的Source值和详细的keys和values:

   

EAnnotation
Source
teamPackage
Details Entry
Key
clientBasePackage
Value
com.ibm
Details Entry
Key
clientPackageSuffix
Value
common.model
Details Entry
Key
dbMapQueryablePropertiesOnly
Value
true

    clientBasePackage表示存放生成代码的package前缀,clientPackageSuffix表示存放生成代码的package后缀,这样在加上EPackage petstore,最终生成的代码将会被放入到com.ibm.petstore.common.model package里。dbMapQueryablePropertiesOnly设为true表示在生成的代码里,只把queryable标签设为true的属性映射到数据库中并在该持久化类的QueryModel里提供对应的查询字段。

    至此,你已经完成了建立所有持久化模型都必须经过的步骤。此时的ecore模型应该如图14所示:

    图 14. ecore模型

    然后,我们开始为Category, Product, Seller三个持久化类建立对应的EClass。我们将以Category的建立过程为例来说明整个过程,读者可以参照这个过程自行建立Product和Seller对应的EClass。

    teamPackage是我们添加EClasses的地方,在EClass里需要定义你希望 存储在Jazz储存库中的持久化对象、对象具有哪些属性、属性都有什么类型和特性,这些都是通过加上一些特殊的Jazz标签完成的,Jazz在以后生成具体的SQL DDL去建表时会去参考这些标签值。

    首先我们在teamPackage里面创建一个名为Category的EClass,并指定它的ESuper Type为SimpleItem,(这里使用SimpleItem而非Auditable,因为我们不需要 保存Category的历史信息)然后我们为Category添加一个名为id的EAttribute到这个EClass中,并设置如下的属性:

Name
id
EType
EInt
Lower Bound
1
Default Value Literal
0

    EType信息表示属性的类型,Lower Bound表示最少出现的次数,填1表示这个这个属性是必须的,填0表示这个属性可选,Default Value Literal表示属性的默认值。然后我们还需要往EAttribute id里添加一个名为queryableProperty的EAnnotations注解,并设置如下的source值和详细的keys和values:

EAnnotation
Source
queryableProperty
 
Details Entry
Details Entry
Key
Key
unique
visibility
Value
Value
 true
 DEFAULT

    unique设为true表示id这个属性在数据库表中必须唯一,visibility设为DEFAULT表示这个属性在生成的POJO中可见。

    然后添加一个名为name的EAttribute到这个EClass中,并设置如下的属性:

Name
name
EType
EString
Lower Bound
0

    我们还需要往EAttribute name里添加两个EAnnotations注解。首先添加名为queryableProperty的EAnnotations注解,并设置如下的source值和详细的keys和values:

EAnnotation
Source
queryableProperty
 
Details Entry
Details Entry
Key
Key
unique
visibility
Value
Value
 true
 DEFAULT

    再添加名为teamProperty的EAnnotations,并设置如下的source值和详细的keys和values:

EAnnotation
Source
teamProperty
 
Details Entry
Details Entry
Key
Key
id
dbStringSize
Value
Value
 false
 SMALL

    我们还需为Category添加一个名为description的EAttribute,添加过程与name EAttribute类似,在此略去读者只需重复上述过程即可。唯一不同的是把dbStringSize调整为LARGE来获取大于2048字节的存储空间。

    最后我们为Category添加名为image的EReference,并设置如下的属性:

Name
image
EType
Content
Lower Bound
0
 Upper Bound
1

    Lower Bound设为0,Upper Bound设为1表示每个Category只有0或1张图片。如果允许每个种类有多张图片可以把Upper Bound设为-1,这样在生成的Category POJO里将会有一个图片的List。

    Category的EClass就建好了,重复上述过程建立Product和Seller的EClass,建完后,整个ecore模型就建好了,如下图15所示:


    图 15. ecore模型

    接下来我们运行Jazz提供的code gen工具,进行从ecore模型到Java代码的自动生成。在Package Explorer 视图中,右键点击petstore.ecore文件然后选择执行Jazz Tools->Generate Component,这样所有持久层的代码都会自动生产到src-gen目录中,如图16所示:


    图 16. 生成的模型层代码

    生成完模型层的代码后,PetStore数据模型层的设计和持久化就完成了.接下来需要进行业务服务层的设计与实现,这将在本系列文章的第二部分中介绍。

    总结

    本文首先介绍了Jazz的技术架构和编程模型,让读者对Jazz技术平台和开发方式有个直观的认识。然后结合PetStore应用实例,详细阐述如何利用Jazz平台的O-R mapping完成数据模型设计和持久化的过程。

    参考资料

    Jazz新手入门为您全面介绍Jazz平台的技术概览,并提供相关的入门学习资源

    Jazz技术文档中心为您提供最新的Jazz技术文档和入门教程,是深入学习Jazz技术的非常好的中文技术资源。

    Hello Jazz介绍了如何编写简单的Jazz组件

    Jazz开发环境搭建

0
相关文章