网上商店系统
PetStore(http://developer.java.sun.com/developer/releases/petstore/)是著名的J2EE学习例程。但是从实用角度考虑,该系统中很多功能无法实现重用。本章讨论网上商店系统,立足实用,并基于前面章节介绍的EJB
Service方法调用框架,讨论如何建立一套快速的数据操作通用框架。
数据的增、删、改、查是信息系统最常用的基本功能。在传统的语言环境中,该功能虽然能够很方便地实现,但扩展性和维护性很差。在J2EE框架下,由于引入了多层结构又显得过于复杂,每个功能的实现需要穿越多个层次才能完成,降低了这些基本功能的开发速度。
本章将针对这种情况,讨论设计出一套J2EE框架下的数据操作通用框架。虽然该框架设计实现时有一定难度,但是使用起来却非常方便,可以在大量不同项目中反复重用,这将大大简化数据的增、删、改、查功能的开发过程,极大地提高J2EE开发速度,同时,又不丧失多层结构的天然优势,继承延续J2EE特有的可伸缩性和可扩展性。
8.1 系统需求和设计
8.1.1 基本业务对象
本系统中,基本业务对象有8个,分别是商品类别(Category)、商品(Product)、商品规格条目(Item)、订单(Order)、订单条目(OrderItem)、订单状态(OrderStatus)、订单地址(Address)和订单客户(Customer)。
8.1.2 数据表设计
8.2 数据操作通用框架
在本系统中,有相当一部分是数据的新增、修改、删除和查询,这些功能分别是在EJB和Web两层中实现的。
在EJB层,通过Facade Session Bean调用实体Bean,实现数据库数据的增、改、删和查,这些都是数据库的基本操作,能非常方便而且有规律地实现。
在Web层,需要通过相应界面来激活后台EJB的数据库操作功能,在使用Strut的情况下,这个过程也是有规律的。
首先看看在一般情况下,增、改、删和查功能是怎样在Struts下实现的,以本项目中的商品类别数据对象Category为例。
8.2.1 框架的提炼和设计
在设计一个框架之前,首先需要明确这个框架操作的对象是什么。
图8-5是从Model Object角度提炼数据对象的增、删、改和查功能抽象原理图,该图将一个数据对象在J2EE中划分为3种Object。第一种是界面显示的表单,这其实是一个ActionForm对象;中间一种是Model或者是DTO,在表现层和EJB层之间实现数据交换;第三种是EJB持久层的实体Bean
Object,代表数据库中数据表数据。
8.2.2 增删改查框架实现
在ModelViewAction代码中,ModelHandler的具体子类是从配置文件中获得,数据对象的key也是这样。使用配置文件,可以将具体的子类实现赋值到这个框架系统中。在这个新的层面框架中,有3个抽象对象需要实现:Model、ModelForm和ModelHandler,它们都要根据具体数据对象,实现不同的子类。这些都是通过modelmapping.xml配置实现的。
8.3 商品类别管理功能的实现
虽然增、删、改、查通用数据操作框架在设计上比较复杂,但是使用起来非常方便。下面以本系统为例,展示该框架结合EJB 和EJB Service调用框架的使用。
8.3.1 创建Session Bean
8.3.2 EJB配置
8.3.3 创建Category相关类实现
8.3.4 Web配置
8.3.5 创建Category.sp
8.4 商品管理功能的实现
8.4.1 创建ProductManager
8.4.2 EJB配置
8.4.3 创建Product相关类实现
8.4.4 Web配置
8.4.5 创建Product.jsp
8.4.6 商品图片上传功能
8.5 商品批量查询和多页显示
在本系统中,一个商品类别下可能有很多商品,这些商品可能需要多个页面才能完全显示。这涉及到一个批量查询、多页显示的框架设计。
该框架需要分别在EJB和Web两个层面实现。EJB实现需要使用DAO+JDBC模式,而Web主要是解决多页显示的问题。
通常的思路是:从数据库中将当前页面需要显示的数据对象查询后,组成数据Model集合,传送到Web层用于显示。
这种思路有一个缺点:将不能使用设置在Web层的Model缓存系统。Web层的Model缓存保存着大量之前调用过的数据Model。在批量规模查询时,不使用这些缓存将浪费很多性能,特别是这些数据Model被不同客户反复调用查询时。
8.5.1 DAO模式
DAO模式是J2EE核心模式中一种,DAO模式主要是在业务核心和具体数据源之间增加了一层,这样实现了两者的解耦。因为具体持久层数据源是可能多样化的,可能是XML或者可能是关系数据库,在具体关系数据库中,也可能有不同的产品如Oracle或MySQL,通过使用DAO模式,业务核心部分就无需涉及具体数据库是如何实现数据库操作的,如图8-10所示。
8.5.2 Struts框架下设计和实现
设计目标的两个功能已经在EJB中实现,剩余的3个功能将需要在Web中实现。在Struts框架下,这3个功能将分别在Action、ActionForm和taglib
3个组件技术中实现。
8.5.3 页导航条实现
以上讨论的是在Strut框架下的实现,ModelListForm实现了页面上数据列表显示。除此之外,还要在JSP页面中实现页导航条显示,如下:
[前页] 1 2 3 4 5 6 [后页]
该导航条使用taglib来实现,有专门的taglib开源项目,这里只是简单地实现一下。实现原理参考Jive论坛的页导航条功能,Jive采取在JSP中写入Java代码的方式实现的,该方式不利于重用和封装,改进方法就是将其转换成JSP
taglib来实现。
8.6 购物车功能的实现
商店客户浏览商品时,可以将愿意购买的商品品种放入购物车,购物车功能使用由状态Session Bean实现,首先根据功能需求进行基本对象建模。
经过分析,购物车有两个基本业务对象:ShoppingCart和CartItem。ShoppingCart代表整个购物车,CartItem则是车中每个购买的品种。CartItem和商品Item有一点区别,CartItem包含Item一些属性,但增加了一个购买数量属性。
8.6.1 有状态Session Bean
EJB ShoppingCart是一个有状态Session Bean。商店客户在浏览多个商品页面,不断地挑选商品,那么之前的购物状态一定要保存,使用有状态Session
Bean保存购物车状态是一个好办法。
注意,有状态Session Bean的引用需要保存在HttpSession中,以便同一个客户再次访问时能获取到同一个有状态Session
Bean。所幸的是,因为这里使用了“EJB方法调用框架”,该机制已经被框架实现了,因此就无需再考虑这些细节了。
8.6.2 WEB功能实现
8.7 小结
一个软件系统一般由两大部分组成:针对本应用的新设计和可重用的软件组件或框架。如果后者占据越大,无疑需要实现的新设计或实现工作量就越小,生产效率越高,成本越低。因此,可根据自己项目领域特点,在J2EE框架下架构设计自己领域的应用框架,提高在该领域软件开发生产的效率,节约成本。
JPetstore轻量源码
|