现在网上流传的很多ssh架构的系统,包括开源的一些应用系统,很多都用了openSessionInView模式,这样一来,整个编程过程将大大简化。session的生命周期在整个请求范围内有效。我们可以把dao查询出来的有延迟加载属性的对象传递到页面中去。
但是在页面输出内容多的情况下,filter会使用页面缓冲区,这时filter的执行时间就和用户的网速有关,因此openSessionInview有可能造成数据库连接不能及时释放的问题。如果不使用openSessionInView,那么我们一般会配置service层的方法使用事务,也就是说我们要在service层将所有延迟加载的属性
都取出来,放到vo中去,这样我们就需要建一系列的vo对象。严格的说,我们要在service层实现vo和po的转换。保存数据时
action :获取formbean,将formbean转换为vo,save(vo)
service: vo->po,dao.save(po) (service层的curd方法都需要用vo做参数?)查询数据时
dao:getList()
servce:遍历list,将list的每一个po转换为vo,有时需要处理po中的明细属性
这样vo和po的转换将带来很多额外的工作。有时感觉很多余。另外有人提出用formbean作为vo,但是formbean是struts的东西,这样vo就和struts耦合,感觉不合理,最重要的是formbean反应的是form提交时的属性,但是查询列表里的对象可能和他的属性并不一样,除非构造一个冗余的formbean来处理输入和输出。vo和form的关系这些问题,期望有高人可以解答。
但是在页面输出内容多的情况下,filter会使用页面缓冲区,这时filter的执行时间就和用户的网速有关,因此openSessionInview有可能造成数据库连接不能及时释放的问题。如果不使用openSessionInView,那么我们一般会配置service层的方法使用事务,也就是说我们要在service层将所有延迟加载的属性
都取出来,放到vo中去,这样我们就需要建一系列的vo对象。严格的说,我们要在service层实现vo和po的转换。保存数据时
action :获取formbean,将formbean转换为vo,save(vo)
service: vo->po,dao.save(po) (service层的curd方法都需要用vo做参数?)查询数据时
dao:getList()
servce:遍历list,将list的每一个po转换为vo,有时需要处理po中的明细属性
这样vo和po的转换将带来很多额外的工作。有时感觉很多余。另外有人提出用formbean作为vo,但是formbean是struts的东西,这样vo就和struts耦合,感觉不合理,最重要的是formbean反应的是form提交时的属性,但是查询列表里的对象可能和他的属性并不一样,除非构造一个冗余的formbean来处理输入和输出。vo和form的关系这些问题,期望有高人可以解答。
ssh框架住要是将"表示层"、"逻辑层"、"数据库层"进行清晰分离。在这里重要的是spring。
你所说的"openSessionInView模式"编程过程未必会大大简化,只是减少了业务或逻辑的交互,利用了可利用的空间
提高相关的效率。延迟加载一般是提前就会被加载到内存中,就是说 相关对象被放到服务器的内存中,如果想调用
此对象从内存中获得。性能和效率完全可以保证。
那里看不到formbean
如果不使用openSessionInView,我们就需要做一些额外的工作,举例如下:
public class Goods{
String id;
GoodsType type;
//getter and setter
}
如果用openSessionInView
那么只需要得到List l = GoodsDao.getGoodsList();
在jsp中,我们可以通过迭代用 good.id ,good.type.name得到物品id,物品类型名称这2个属性如果不用openSessionInView
那么我们可能需要建一个GoodsVO(日后需要增加一个字段比如价格price,我要改Goods,GoodsForm,现在又要多改一个GoodsVO)
public class GoodsVO{
String id;
String typeName;//页面需要显示type的name如果日后需要显示type的descript,那么我又要在vo加一个属性,对应的service也要改!!
而openSessionInview在页面里good.type.descipt就可以了,不用任何改动
}
然后我们在service里
List l = GoodsDao.getGoodsList();
List result = new ArrayList();
//已经得到list了,却还要遍历再封装一个vo list
for(int i=0;i<l.size();i++){
Goods g = (Goods)l.get(i);
GoodsVO gv = new GoodsVO();
gv.setId(g.getId());
gv.setTypeName(g.getType().getName())
.....一系列的set方法....
(增加一个字段,这里又要改)
result.add(gv);
}
对比一下,如果用openSessionInView,代码量和维护量都要比不用少。
现在已经很明确的知道了openSessionInView存在弊端,需要增加vo,在业务层就获取各个关联的lazy属性然后关闭session
可是这样感觉好像很多地方都在做重复的复制。
另外有人提出用formbean作为vo,但是formbean是struts的东西,这样vo就和struts耦合,感觉不合理,最重要的是formbean反应的是form提交时的属性,但是查询列表里的对象可能和他的属性并不一样,除非构造一个冗余的formbean来处理输入和输出。vo和form的关系
————————————————————————————————————————————————————————————————————————
个人觉得如果为了简化编程过程而采取这种方式不太可取,不仅带来了分层的混乱和耦合,而且容易使自己思维混乱,同时也觉得不安全。
另,20楼的哥们真是.................性情中人啊!
1 声明一个对象,然后在formbean中引入这个对象
2 使用struts1的动态form,引入一个外部对象这个对象,可以是vo、po,因为他是pojo,呵呵以上两种都是最常用的方法。
他们公司是自己的framework,
他们自己封装的,
我就感觉其实很多时候没有必要非要哪种框架
只要能解决问题,并保证效率,使用哪种框架或技术都可以
将session的关闭一直延迟到表示层如果想解决这个问题,LZ的方案虽然可行,但是会造成非常大的代码量和vo转换的耗费的时间
还有一种,就是尽量不用关系连接,不用延迟加载,不过这样也会造成性能问题所以,没有一种方案是最优的
如果不是对网速要求非常苛刻,建议还是用opensessioninview的好
如果性能问题跟不上,那就不要用hibernate的好,换别的orm可能更好一点
归根结底,选合适的就好
如果不用延迟加载,同时又设定了关联关系,那么很多时候会做不必要的关联查询
如果用了延迟加载,又不用openSessioninView,则必须在service层去将需要使用的延迟加载的属性都取一遍
所以,当你做查询的时候,如果想做关连查询,那么你就手工fetch抓取,比如用createQuery查询
如果认为opensessioninview效率低的话,就可以这么
所以,当你做查询的时候,如果想做关连查询,那么你就手工fetch抓取,比如用createQuery查询
如果认为opensessioninview效率低的话,就可以这么
----------------------------------------------------
这样的话,关联其实就没有带来什么便利了,还是要自己去手动查询。
就是这个地方觉得很矛盾。
hibernate的延迟加载就是为了能够按需去加载关联对象,可是按照分层的原则,我们又要在service层就把延迟加载的属性确定下来,其实很多时候需要哪些
属性是在jsp中才确定的
例如
user有 相关订单集合orders,相关文章news,相关资源集合files....
这些属性一般都是延迟加载的,我们的getUser方法一般都不会去取这些属性,但是我的一个jsp要用,因此就要去加一个方法getUserWithXXX把这些属性先取出来
直接把那些id的属性都用String表示,然后各种关联的集合,对象都按需要去取应该也不会麻烦多少吧。
听过很多人说他们的系统里从来不用关联。
既然你的系统对性能要求这么苛刻,换ibatis吧,hibernate不是万能的
taobao用ibatis不也用的挺好的吗