使用Spring和Hibernate实现树型结构列表
最近在自学RoR,看到了rainlife的帖子Rails生成Ext Tree,结合以前的Java项目经验,提出了我的一些想法。
以下的文字和rainlife的帖子Rails生成Ext Tree中我的回复大致相同,只是以SSH架构的Java代码重新实现了原帖中的内容。
我的疑问主要是在数据库的设计上,对于其中lft和rgt字段的设计感觉不好。当然我刚刚开始学习RoR,其中也许有很完备的解决方案我不知道,仅在此提出我的看法而以,如有异议,欢迎批评指正。
维护一个树型结构的类型列表,如下所示:
Root
|- Child 1
| |- Child 1.1
| |- Child 1.2
|- Child 2
|- Child 2.1
|- Child 2.2
原帖中表示树状节点的Category类中有lft和rgt这两个字段看上去是用来定义一个类型边界的。如果需要查找某个特定类型及其子类的话,则先查找该类型的lft和rgt,然后再 (lft > ? and rgt < ?) 获得其子类。
这种设计在数据结构完备的情况下能准确的统计出所有的子类。但是我要动态的增加Child子类,或者改变Child的隶属关系的时候,就需要对数据库表中所有数据的lft和rgt做出调整。比如我要在Child 1中增加一个Child 1.3。相应的 Root、Child 1、Child 2、Child 2.1、Child 2.2 的lft和rgt都要做相应的变化。
也许acts_as_nested_set可以通过先 delete from category; 后 insert into values(?,?,?,?); 的方式进行全类的维护,但是如果别的类有对Category的引用(即外键)。这样的隶属关系不是会产生混乱了吗?况且如果数据库真的建立了外键的话,也不允许 delete from category; 操作的。
所以我的考虑是用一个level字段代替lft和rgt字段,level字段维护着Category实例的层级关系。
例如,将root的level定义为1(这个在数据库或程序中可配),那么Child 1的level就为1|${id}(其中'|'为Level分层标记,${id}表示当前数据Id或其它可唯一标识的字段值),假定为1|2,同理Child 1.1的level就是1|2|3。
类结构如下所示:使用的是annotation的hibernate
原帖中是用Ext来实现视图的现实。我只需要在Struts2中使用JSONUtils实现一个Result,使得Action返回一个JSON对象,就可以在JSP中用Ext来显示树型结构的列表
显示的效果如下:
String hql = "from Category where level like ? order by id desc";
return crudDao.query(hql, root.getLevel + Category.LEVEL_SPLIT + "%");
但我觉得不对啊,这会把子树的子树也查出来的啊,能否解释一下呢,再好能发个完整的源代码上来。谢谢。crudDao.query(hql, root.getLevel + Category.LEVEL_SPLIT + "%");weijiang8410 2 小时前:crudDao.query(hql, root.getLevel + Category.LEVEL_SPLIT + "%");
但我觉得不对啊,这会把子树的子树也查出来的啊,能否解释一下呢
7 楼 liujiew 2008-06-12 不错哦!