论坛首页 Java企业应用论坛

使用Grails实现树形结构无限级分类

浏览 5447 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-02-21  
为了用grails实现无限级分类的应用如组织机构、目录、系统菜单等,我碰了几次错,现终于解决了,写出来做个记录.
如果要实现无限级的系统菜单,我们实现的类如下
class SystemMenu {
   String name;
   String description;
   SystemMenu parent;
   static belongsTo =[parent:SystemMenu ]
   static hasMany = [childrens:SystemMenu];  
}

意思是:一个菜单项属于它的上级菜单[parent],同时又有它的子菜单[childrens]。
但用上面的类来实现的话,数据是无法保存的,首先报的一个错是:
[class SystemMenu]类的属性[parent]不能为null
这是因为新增第一条数据时没有上级菜单,我想能不能在数据库中先初始一条数据
但还是不行,出现约束违例手工插不上数据;没办法试了一下parent_id字段等于本记录的ID
可以插入数据了,再用grails试新增一条数据时,grails进入了死循环,因为上级菜单的数据的上级指向了自己。
后来把类改成
class SystemMenu {
   String name;
   String description;
   SystemMenu parent;
   static belongsTo =[parent:SystemMenu ];
   static hasMany = [childrens:SystemMenu];
   static constraints = {
        parent(nullable:true)
    }  
}

让parent_id字段可以为空,结果就解决了问题,数据操作不再出现问题,可以自关联的应用。其实也可以这么实现:
class SystemMenu {
   String name;
   String description;
   SystemMenu parent;
   static belongsTo =[parent:SystemMenu ]
    static hasMany = [childrens:SystemMenu];
    static mapping = {
       parent:[column:'parent_Id',lazy:"true",cascade:"none"]
       children joinTable:[name:'children', key:'parent_Id', column:'Id',lazy:"true",inverse:"false",cascade:"none"]
    }
    static constraints = {
        parent(nullable:true)
    }  
}


grails 真的好用
   发表时间:2008-02-21  
呵呵,确切的说,是GORM实现的
0 请登录后投票
   发表时间:2008-02-21  
呵呵,感谢分享

曾见过一个用js实现的,05年的一本书啦,原理一样
0 请登录后投票
   发表时间:2008-02-25  
我想请问一下,关于上面的级联问题.
前几天,我也在做类似的问题,但是现在我需要一个限制条件,就是当删除它的上级时,所用的cascade为save-update,即不删除它的下级关联,仅是做更新.
但是无论我使用上面的第一个例子,还是第二段代码,它的更新都是采用的delete模式,会级联删除它的所有下级.即使将cascade,改为save-update模式,也不会有任何作用.
我想请问一下,如何处理这种情况.现在一直在郁闷中,参考文档上的例子,也没有说得很明白,有人知道这个问题么?
0 请登录后投票
   发表时间:2008-02-27  
我想象你这样的需求估计只用配置是不能实现的,你得1.保证数据表没有FOREIGN KEY 要不然数据库是不让删除存在子目录的目录的;2.在你做删除时要自己update它的子目录。这样配置一对多:parent:[column:'parent_Id',lazy:"true",cascade:"none"]不用belongsTo;
去掉数据表中:FOREIGN KEY (`parent_id`) REFERENCES `system_menu` (`id`)的约束;在delete目录前update它的子目录的parent_id为空。
0 请登录后投票
   发表时间:2008-02-27  
我试了一下这样可以实现你的需求:
class SystemMenu {   
   String name;   
   String description;   
   SystemMenu parent;   
    static hasMany = [childrens:SystemMenu];   
    static mapping = {   
       parent:[column:'parent_Id',lazy:"true",cascade:"none"]   
    }   
    static constraints = {   
        parent(nullable:true)   
    }     
}  


CREATE TABLE `system_menu` (
  `id` bigint(20) NOT NULL auto_increment,
  `version` bigint(20) NOT NULL,
  `description` varchar(255) NOT NULL,
  `name` varchar(4) NOT NULL,
  `parent_id` bigint(20) default NULL,
  PRIMARY KEY  (`id`),
  KEY `FKA47C616F1886D91E` (`parent_id`),
  CONSTRAINT `system_menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `system_menu` (`id`) ON DELETE SET NULL
)

主要是把表约束 加上“ON DELETE SET NULL”语句,MYSQL下测试过,不用在删除时自己update子目录。
如果要做成删除一个目录,它下级的子目录要归到要删除目录的父目录的话,估计要自己写update子目录了。

0 请登录后投票
   发表时间:2009-01-07  
今天忽然才发现grails的一个插件,menu插件。完全可以用~~~~~~~~~用法并不复杂


grails的插件机制真是好
0 请登录后投票
论坛首页 Java企业应用版

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