在 struts+ hibernate 这种结构中,是不应该把hibernate产生的po直接传递给jsp的,不管他是iterator,还是list,这是一个设计错误。
我来谈谈在j2ee架构中各层的数据表示方法:
web层的数据表示是formbean,数据来源于html form post
业务层的数据表示是vo
持久层的数据表示是po,其数据来源于数据库,持久层的数据表示例如cmp。在一个规范的j2ee架构中,不同层的数据表示应该被限制在层内,而不应该扩散到其它层,这样可以降低层间的耦合性,提高j2ee架构整体的可维护性和可扩展性。比如说web层的逻辑进行了修改,那么只需要修改formbean的结构,而不需要触动业务层和持久层的代码修改。同样滴,当数据库表进行了小的调整,那么也只需要修改持久层数据表示,而不需要触动业务层代码和web层代码。
不过由于hibernate的强大功能,例如动态生成po,po的状态管理可以脱离session,使得在应用了hibernate的j2ee框架中,po完全可以充当vo,因此我们下面把po和vo合并,统称为po。
先来谈谈actionformbean和持久层的po之间的重大区别:
在简单的应用中,actionformbean和po几乎是没有区别,所以很多人干脆就是用actionformbean来充当po,于是actionformbean从jsp页面到servlet控制层再到业务层,然后穿过持久层,最后一直映射到数据库表。真是一竿子捅到了底!
但是在复杂的应用中,actionformbean和po是分离的,他们也不可能一样。actionformbean是和网页里面的form表单一一对应的,form里面有什么元素,bean里面就有什么属性。而po和数据库表对应,因此如果数据库表不修改,那么po也不会修改,如果页面的流程和数据库表字段对应关系不一致,那么你又如何能够使用actionformbean来取代po呢?
比如说吧,用户注册页面要求注册用户的基本信息,因此html form里面包含了基本信息属性,于是你需要一个actionformbean来一一对应(注意:是一一对应),每个bean属性对应一个文本框或者选择框什么的。
而用户这个持久对象呢?他的属性和actionformbean有什么明显不同呢?他会有一些actionformbean所没有的集合属性,比如说用户的权限属性,用户的组属性,用户的帖子等等。另外还有可能的是在actionformbean里面有3个属性,分别是用户的first name, middle name, last name,而在我的user这个持久对象中就是一个 name 对象属性。
假设我的注册页面原来只要你提供first name,那么actionformbean就这一个属性,后来我要你提供全名,你要改actionformbean,加两个属性。但是这个时候po是不应该修改滴,因为数据库没有改。
那么在一个完整的j2ee系统中应该如何进行合理的设计呢?
jsp(view) ---> action form bean (module) ---> action(control)
action form bean是web层的数据表示,它和html页面form对应,只要web页面的操作流程发生改变,它就要相应的进行修改,它不应该也不能被传递到业务层和持久层,否则一旦页面修改,会一直牵连到业务层和持久层的大面积的代码进行修改,对于软件的可维护性和可扩展性而言,是一个灾难,actiont就是他的边界,到此为止!
action(web control) ---> business bean ---> dao ---> orm --->db
而po则是业务层和持久层的数据表示,它在业务层和持久层之间进行流动,他不应该也不能被传递到web层的view中去,而actionservlet就是他的边界,到此为止!
然后来看一看整个架构的流程:
当用户通过浏览器访问网页,提交了一个页面。于是action拿到了这个formbean,他会把formbean属性读出来,然后构造一个po对象,再调用业务层的bean类,完成了注册操作,重定向到成功页面。而业务层bean收到这个po对象之后,调用dao接口方法,进行持久对象的持久化操作。
当用户查询某个会员的信息的时候,他用全名进行查询,于是action得到一个usernameformbean包括了3个属性,分别是first name, middle name, last name,然后action把usernameformbean的3个属性读出来,构造name对象,再调用业务bean,把name对象传递给业务bean,进行查询。
业务bean取得name(注意: name对象只是user的一个属性)对象之后调用dao接口,返回一个user的po对象,注意这个user不同于在web层使用的userformbean,他有很多集合属性滴。然后业务bean把user对象返回给action。
action拿到user之后,把user的基本属性取出(集合属性如果不需要就免了),构造userformbean,然后把userformbean request.setattribute(...),然后重定向到查询结果页面。
查询页面拿到request对象里面的actionformbean,自动调用tag显示之。
总结:
form bean 是web层的数据表示,他不能被传递到业务层;po是持久层的数据表示,在特定情况下,例如hibernate中,他可以取代vo出现在业务层,但是不管po还是vo都必须限制在业务层内使用,最多到达web层的control,绝不能被扩散到view去。
form bean 和po之间的数据转化是在action中进行滴。
闽公网安备 35060202000074号