锁定老帖子 主题:Hibernate Iterator的问题
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2003-09-17
但是,在session关闭的情况下,Iterator里的数据就不能用了, 这这这这怎么办? 通常我是在一个bean里取得session,创建事务,然后调用其他bean进行数据获取,操作,在return之前关闭session,再返回actionbean,把取出数据丢到jsp里面去,这样的话,不用List,数据在页面里根本不可用啊 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2003-09-17
从你的描述来看,莫非你直接把Hibernate Iterator 传递给JSP?我要确定你的设计方案才能回答你的问题。
|
|
返回顶楼 | |
发表时间:2003-09-17
这样太麻烦了,还是做一个Filter,在处理完jsp页面之后再close Session,这也是Hibernate推荐的做法。
|
|
返回顶楼 | |
发表时间:2003-09-17
用Filter不是就绑死在BS上了吗。
再说,也不是每个servlet都需要连接数据库吧 shmin的方法……性能比直接用list有提升吗? to robbin: 举个例子啊,用struts的 DB - DAO - 业务Bean - Action - JSP 我是在业务Bean 里创建session ,发起事务的, 把session 传给 DAO,进行持久化或者得到数据的。 一个业务完了,事务和session也就close了,干干净净。 然后把数据通过action甩个JSP做显示。 问题就在于,jsp显示的时候 session已经关了,iterate就next不出来了。 倒是list这种一次读入的还能健在 |
|
返回顶楼 | |
发表时间:2003-09-17
在 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) ---> ActionFormBean(Module) ---> Action(Control) ActionFormBean是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显示之。 总结: FormBean是Web层的数据表示,他不能被传递到业务层;PO是持久层的数据表示,在特定情况下,例如Hibernate中,他可以取代VO出现在业务层,但是不管PO还是VO都必须限制在业务层内使用,最多到达Web层的Control,绝不能被扩散到View去。 FormBean和PO之间的数据转化是在Action中进行滴。 BTW: JDO1.x还不能像Hibernate功能这样强大,PO不能脱离持久层,所以必须在业务层使用VO,因此必须在业务层进行大量的VO和PO的转化操作,相对于Hibernate来说,编程比较烦琐。 |
|
返回顶楼 | |
发表时间:2003-09-17
VO <--> PO 完全分开的话,会导致每次访问都有大规模的VO <--> PO的赋值行为的。
因为hibernate如此强大,虽然VO跟PO不可能一一对应,但是可以根据使用情况把一些大PO拆成几个小PO的,比如User可以包括 Auth (username,password) Name (first,last...) 等等,这样可以一次取出部分数据而不是全部,试想如果User 如果包含一个个人生平的大字段的话,是否有必要每次读出? 而通一张表,也可以根据使用情况不同同时存在多个PO。 FormBean 就可以包括一个或者多个 PO(VO),即便有的时候不需要全部使用,空着几个属性也没关系吧 public class UserForm extends ActionForm { private Auth auth; private Name name; ...... } 我觉得FormBean也应该是基本固定的,只要涵盖了要要传递的内容就行了,没必要也不可能那么严丝合缝儿吧 每次都转换一下,表,页面多的话,工作量一下大的没边儿了 |
|
返回顶楼 | |
发表时间:2003-09-17
这是设计的策略问题,理论是一回事,实际操作也不一定非要这样干,你可以自行取舍,在实际项目中灵活一点,增加一点bad smell,提高开发效率。只不过在大型项目中最好还是严丝合缝,不然的话,改版的时候会痛苦的很滴。
|
|
返回顶楼 | |
发表时间:2003-09-18
macula 写道 只有Iterator才能享受JCS的性能提高,
但是,在session关闭的情况下,Iterator里的数据就不能用了, 这这这这怎么办? 通常我是在一个bean里取得session,创建事务,然后调用其他bean进行数据获取,操作,在return之前关闭session,再返回actionbean,把取出数据丢到jsp里面去,这样的话,不用List,数据在页面里根本不可用啊 我也遇到了这个问题!!!!!!!! 最好的解决方法是什么?Iterator取出数据后,应该怎了处置? |
|
返回顶楼 | |
发表时间:2003-09-18
就是上面shmin的方法阿,这种方式是正解!!!
|
|
返回顶楼 | |
发表时间:2003-09-18
首先假设我们都是在Action中数据转化VO与FormBean的:
我赞成yehs220说的方法,简单明了. 何况用filter也不是用在所用的servlet, 我们可以做一些map设定。有选择的filter servlet. 取数据的时候用list, 这样数据可以cache到JCS中,以后直接使用iterator,利用JCS。 至于, 数据集打包的方式,由于涉及到打包数据集而后又解包,即麻烦又影响速度,为什么不直接用list? |
|
返回顶楼 | |