Archive for July 9th, 2004
关于在页面(表现层)里PO保持和传递的做法
Posted on July 9, 2004 - Filed Under Uncategorized
之前老是听说应不应该把PO传递到表现层(先别跟我讨论概念问题)
我老是不明白究竟怎样把PO传递到表现层
后来看到有某一说法是直接把PO传递到表现层会造成lazy load然后在view open hibernateSession并通过filter来close hibernateSession
这种做法挺好的,不过不是今天我这里的问题
我的问题是怎么把PO传递到表现层然后又返回到Action(Control)呢?
这个问题出现在编辑数据页面里
以前的做法(不把PO传递到表现层的做法)就是构造一个FormBean(或者应该叫做DTO?)记录需要修改的属性,并且记录主键id。整个流程大概是,先load PO,beancopyprop FormBean,页面修改了后,根据主键id再load一次PO,然后beancopyprop一次,再update。所以造成update之前必须select一次,这样并不太优雅,而且无法使用PO的version属性,也就是可能会造成脏数据。
现在hibernate的PO可以脱离hibernateSession然后再次进入,使得我们使用PO的时候多了一种选择,就是不构造FormBean(DTO),让PO直接渗透表现层再回到Action(Control)。问题是怎么让PO渗透表现层再回来呢,目前我所知道的就是使用httpSession保存渗透的PO,这也是大多数新的mvc framework和hibernate结合时使用的方法,像webwork2的adminapp demo、spring mvc、tapestry
本来贴在javaeye论坛里
http://forum.javaeye.com/viewtopic.php?t=6108
我花了一天时间整理了一堆思路出来竟然没有人理我
首先先说明我是最近研究webwork2的时候发现这个问题的,后来我发现所有mvc都必须面对这个问题
在一个edit过程里,先通过一个loadAction(control)提取原始数据,然后展现在view里,用户修改了后通过updateAction(control)提交修改数据
流程如下
loadAction -> view -> updateAction
问题时怎么把loadAction里获得的数据(如Bean、PO)经过一个view(jsp或别的)传递给updateAction
假设我们操作的对象是User
如果User是一个hibernate的PO的话
把它放在httpSession里不失为一种好方法
页面里直接对httpSession里的user操作
当进行saveAction的时候
从httpSession里拿到的user就能直接用hibernateSession.update回数据库
这也是那个webwork2+hiberate的demo adminapp里的做法
ps,adminapp在这里http://wiki.opensymphony.com/display/WW/Examples
但是比较严重的问题就是不能同时打开两个修改user的页面,另外就是如果不在使用完以后立刻删除该httpSession变量的话就是持续占有服务器内存
如果不用httpSession的话,就必须把user里不需要显示到页面的属性用hidden记录下来,但是如果user有list(一对多或多对多关系)那怎么办呢?这似乎无法解决,折中的解决办法就是把主键id写到hidden里,然后在saveAction里使用select&update的方法(这里可以构造一个formBean),这也并不优雅
后来我带着这个问题去看spring的mvc
发现spring的mvc已经考虑了这个问题
一下是spring里带的demo petclinic
editOwner的操作action
package org.springframework.samples.petclinic.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.springframework.samples.petclinic.Owner;
import org.springframework.web.bind.RequestUtils;
import org.springframework.web.servlet.ModelAndView;
/**
* JavaBean Form controller that is used to edit an existing Owner.
*
* @author Ken Krebs
*/
public class EditOwnerForm extends AbstractClinicForm { [...]