论坛首页 Java企业应用论坛

领域模型的超延迟加载初步设计

浏览 6100 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-12-09   最后修改:2008-12-09
最近,taowen 同学引发的 领域模型的价值与困境等讨论,非常热烈。

尤其taowen 在 贫血的Domain Model 中的RichSet  设计和我想到一处去了,呵呵。我顺带补充一下就 RichSet 我的想法,欢迎拍砖。

    经常见到有朋友担心这样的问题, hibernate下 user.getTasks(), 一加载,所有的关联数据就都load到内存里了。 其实按理 Framework 设计人员应该解决这个棘手的问题。

因此应该给集合类,List,Set,Bag等赋予行为,采用Super Lazy Load。超延迟加载技术。
1)  user.getTasks() 时,不去load数据。 tasks.get(0), 时采取load数据;
2)  tasks.get(0),并不全部load数据,采用分页方式,默认 pagesize可以配置,load出第一页数据;
3) tasks.get( x ), 也只load出 x 所在页的个记录。
4) 数据集合 tasks 作为一个 集合实例,应该保持一个query condition对象,以便在需要的时候和 持久层(可以是 DB,文件,内存,或另一个WebService系统)进行同步。
5) user.getDpartment() 这样的对 1 的关联也可以 lazy(目前hibernate等是支持的),super lazy load 下,可以在第一个属性访问的时候,例如 department.getName() 的时候,再去load。当然,策略可配。

大量数据的加载效率,重复加载等,由 cache 系统保证。
这样设计的目标就是让将 bulk 数据加载和处理的问题放回到底层,让程序员中心放到领域模型的业务上去。
   发表时间:2008-12-10  
无非三个方式:
1.保证整个线程结束之前session 一直打开。用得最多的是OpenSessionInViewFilter.假如request时间跨度不长的话,首选的方式。
2.“预取”所有需要用到的数据。当然啦,会拔出萝卜带出泥,lazy load Collections 需要自己过滤,而且过滤之后需要很有技巧的使用这个collection,过滤仍然在session关闭前,而且过滤后的collection不能再绑回到root entity上去,否则可能会有严重问题。
3.重新绑定一个新的session。这个是hibernate 文档反对的做法。

第二种方式的难度在于不带出泥,视乎没什么很好的办法,对于user.getTasks()使用不应有两种语义,不应该返回过滤后的集合。2级缓存很好的解决效率问题,只拔一次萝卜,当然啦,过滤还是靠你的程序和你自己的缓存技巧了。
0 请登录后投票
   发表时间:2008-12-10  
QueryableCollection的技术难度攻关已经完成了,还有待进一步完善其功能.代码参见:
http://javaonhorse.googlecode.com/svn/trunk/javaonhorse-query/
0 请登录后投票
   发表时间:2008-12-10  
taowen 写道
QueryableCollection的技术难度攻关已经完成了,还有待进一步完善其功能.代码参见:
http://javaonhorse.googlecode.com/svn/trunk/javaonhorse-query/

看了一下。允许提些意见不?呵呵
0 请登录后投票
   发表时间:2008-12-10  
llade 写道
taowen 写道
QueryableCollection的技术难度攻关已经完成了,还有待进一步完善其功能.代码参见:
http://javaonhorse.googlecode.com/svn/trunk/javaonhorse-query/

看了一下。允许提些意见不?呵呵

当然可以
0 请登录后投票
   发表时间:2008-12-10  
扩充的可查询的Collection类,我觉得应该支持一种类似xpath或者el表达式的根据“类script”的方式去设置条件 或者 取对象和对象的集合。api的编程的方式去取总有不灵活的地方。我看了一下Qset的例子,createParameter的返回的是个entity,以entity作为条件类有个局限,隐含的是a = xxx and b=xxx .....,而不能做到a = xxx or b=xxx .....也不能做到大于小于,而且和hibernate的findByExample方式重复的感觉。或者可以说QuaryableCollection查询的扩充只有一种“垂直模式”,复用功能有点弱哦。不过我只是从你的例子上粗粗看的。也可能一叶障目。
0 请登录后投票
   发表时间:2008-12-10   最后修改:2008-12-10
我心目中的代码是这样的:
lily.children.findBy("name","Tom").and().findBy("isMale",true).or().findBy("name","Beth");
//等价script:name = 'tom' and isMale or name = 'Beth'.
0 请登录后投票
   发表时间:2008-12-10  
或者:
lily.getChildren().getCondiction().eq("name","Tom").and().qe("isMale",true).or().eq("name","Beth").list();
0 请登录后投票
   发表时间:2008-12-10  
或者:
lily.getCondiction().enter("children").eq("name","Tom").and().qe("isMale",true).or().eq("name","Beth").list();
//enter("children")表示进入子实体。
扩展一下。
或者lily.getCondiction().enter("children").enterQuote().eq("name","Tom").and().qe("isMale",true).endQuote().or().eq("name","Beth").list();
//等价script:(name = 'tom' and isMale ) or name = 'Beth'.
0 请登录后投票
   发表时间:2008-12-10  
不过感觉已经是在写类 HQL 的script了。呵呵
0 请登录后投票
论坛首页 Java企业应用版

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