论坛首页 Web前端技术论坛

[原创]Ajax和LazyLoad的冲突

浏览 20036 次
该帖已经被评为良好帖
作者 正文
   发表时间:2006-09-26  
  如果你的项目中同时使用了ajax和orm工具,那你就应该注意这篇文章,或许你也碰到过这个问题。

  乍一看标题,或许很多人都很迷糊,ajax和orm的lazyload有什么关系,那里来的冲突?是啊,乍一看,一个是前端,一个是后端,基本没有关系的,怎么就有了冲突。如果你使用了remote call调用服务器端方法,并且得到返回的po的时候,就很有可能出现这种问题。

  先看看lazyload的含义,lazyload是为了防止n+1问题同时节省资源的一种做法,比如,我有一张用户表(user),一张订单表(order),一张货物表(item), user和order是1:N的关系,order和item假设1:1的关系。当我们使用orm工具的时候,一般可能会这么定义, user对象中存在一个由order对象组成的Set或List,而order和item之间还各存在一个Item和Orer对象。正常情况下,取得一个user对象的时候,如果不需要相关的order信息,只要不去显示访问order列表的get方法,orm工具是不会去加载和当前user对象关联的order列表的。当我们要这些order信息的时候,仅仅访问其get(Java) 方法或者其属性(.Net),orm工具会自动的帮我们加载这些对象。

  但是不幸的是,如果你通过ajax的remotecall来得到一个User对象,那么你的lazyload就会失控了。我们知道现在的 ajax框架都是支持remotecall的(据我所知),它的一个好处就是客户端js可以直接访问服务器端方法,并且ajax框架能够以一种协议将服务器端返回的po对象转换成js对象。那么在回到刚才所提到的User对象,当通过remotecall得到一个User对象的时候,ajax框架会遍历User对象的get方法或者属性同时生成一个纯js的object,,在遍历的过程中,它会把加载该user的ordet列表,order关联Item,Item也被加载了。Lazyload就会在你意向不到的情况下失效了。

  如果你对象中存在树的结构,那么这里就会无限制的一直加载下去,直到把整棵树全部加载完毕,而且可能你还根本不知道会有这个问题。正是今天碰到这个奇怪并隐讳的问题,花费了我几个小时的时间,才真正的找出根本原因。

  建议大家在使用ajax的同时尽量少使用这种方式,尽量使用更新局部页面的办法,而不是通过remotecall获得po,动态生成dom。有一个解决的办法就是,把需要lazyload的属性以及访问方法都设置成private,另外通过其他方法来调用。这样就能避免转换对象的时候导致你的lazyload失效。
   发表时间:2006-09-26  
Remoting的时候必须在服务器端提供一个相应的Service层,把PO对象图转换为扁平的DTO。
0 请登录后投票
   发表时间:2006-09-26  
好快的回复。呵呵~

如果是单独一个po转换成DTO我到觉得没什么,但是如果客户端得到的是一个对象集合,那不是还需要遍历这个集合去进行转换?反而会感觉不爽。
0 请登录后投票
   发表时间:2006-09-26  
这个问题很容易解决,服务器端做一个JSON的Serializer和Deserializer就可以了。
0 请登录后投票
   发表时间:2006-09-26  
Nicholas_Ding 写道
这个问题很容易解决,服务器端做一个JSON的Serializer和Deserializer就可以了。


不好意思,听说过JSON但一直没有用过,能举个简单的例子么?

我先猜测一下,如果不对请指正:
  是自己实现Serializer,Deserializer吗?如何来判断某个属性是否需要Serialize?如果一个对象中关联了多个对象,那么客户端可能会有多种情况:可能会都不laod,可能会只load A或者load B或者AB都load,那又如何来判断究竟是那种情况?
0 请登录后投票
   发表时间:2006-09-26  
用ajax获取对象图,我的建议是一定要在服务器端做对象图的裁剪。可以通过一个配置文件来决定如何裁剪一个对象图。
0 请登录后投票
   发表时间:2006-09-26  
其实我发这个帖子的原意并不是很关心有什么解决办法。

我更想知道的是为什么你会提出这个解决办法?怎么去实现?

这样讨论才有价值,而且也是我的目的。
0 请登录后投票
   发表时间:2006-09-26  
http://getahead.ltd.uk/dwr/server/hibernate
dwr是这样搞的。

DTO
如果不用open session in view,根本没有这个疑问的。

我很怀疑  ajax和服务器端OO编程思想 本质上有冲突。
0 请登录后投票
   发表时间:2006-09-26  
zkj_beyond 写道
http://getahead.ltd.uk/dwr/server/hibernate
dwr是这样搞的。

DTO
如果不用open session in view,根本没有这个疑问的。

我很怀疑  ajax和服务器端OO编程思想 本质上有冲突。


Web Remoting本来就是不OO的,是过程化调用。
0 请登录后投票
   发表时间:2006-09-26  
foxty 写道

不好意思,听说过JSON但一直没有用过,能举个简单的例子么?

我先猜测一下,如果不对请指正:
  是自己实现Serializer,Deserializer吗?如何来判断某个属性是否需要Serialize?如果一个对象中关联了多个对象,那么客户端可能会有多种情况:可能会都不laod,可能会只load A或者load B或者AB都load,那又如何来判断究竟是那种情况?


很多情况下都是Java把简单的事情弄复杂了。
AJAX 不需要 Lazy Loading,或者说和 Hibernate 提供的不太一样,Robbin 说的没错,最好的做法就是用 DTO,用一个 Serivce Facade。

json 几乎成为了 ajax 通讯的标准协议,注意,Java 有类型并不说明其他语言也一定要带有类型,做 ajax 有时你会发现带类型是个累赘。Java 的话建议用一下 DWR 试试。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics