GORM 中的树结构(grails)

发布于 2024-11-04 15:50:24 字数 574 浏览 4 评论 0原文

我正在尝试在 GORM 中定义树结构。这是我的模型:

class Tree {
    String name
    Level rootLevel

    static hasOne = [rootLevel: Level]
    static hasMany = [levels: Level]
    static mappedBy = [levels:"parentTree"]
}

class Level {
    String name
    Tree parentTree
    Level parentLevel
    Set<Level> subLevels

    static belongsTo = [parentTree: Tree]
    static hasMany = [subLevels: Level]
}

插入似乎工作正常,但是当我无法加载具有许多级别和子级别的树时。 我想我错过了关系中的一些东西: - 树应该有一个对 rootLevel 的引用(以及可选的所有子级别) - 一个关卡应该有一个对其父关卡、子关卡和全局父树的引用,

你能指出我获得这样的树结构的正确方向吗? 谢谢

I'm trying to define a tree structure in GORM. Here is my model:

class Tree {
    String name
    Level rootLevel

    static hasOne = [rootLevel: Level]
    static hasMany = [levels: Level]
    static mappedBy = [levels:"parentTree"]
}

class Level {
    String name
    Tree parentTree
    Level parentLevel
    Set<Level> subLevels

    static belongsTo = [parentTree: Tree]
    static hasMany = [subLevels: Level]
}

Insertion seems to work fine, but when I can't load a Tree with many levels and sublevels.
I guess I missed something in the relations:
- the Tree should have a reference to the rootLevel (and optionally to all sublevels)
- a Level should have a reference to its parent level, its sublevels and the global parent Tree

Could you point me out the right direction to get a tree structure like this ?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

五里雾 2024-11-11 15:50:24

我不喜欢你的树结构,所以我创建了自己的:)

Class TreeNode {
    String name
    TreeNode parent

    static hasMany = [children: TreeNode]

    //returns the root node, and by extension, the entire tree!
    TreeNode getRootNode(){
       if(parent){
          //if parent is not null then by definition this node is a child node of the tree.
          return parent.getRootNode()
       }else{
          //if parent is null then by definition it is the root node.
          return this
       }
    }

    //you might not need this function, but ill add it as it is common in tree structures
    boolean isLeaf(){
       //determines if this node is a leaf node. a leaf is a node with zero childrens
       return children.isEmpty()
    }
}

至于确保加载所有树节点,你总是可以对每个树节点(父节点和子节点)使用急切/非延迟获取。但是,如果您的树结构非常大,则可能会造成性能损失......

至于急切/惰性获取。看一下这里: ​​在 Grails / Gorm 中使用惰性属性获取< /a>

I didn't like your tree structure, so i created my own :)

Class TreeNode {
    String name
    TreeNode parent

    static hasMany = [children: TreeNode]

    //returns the root node, and by extension, the entire tree!
    TreeNode getRootNode(){
       if(parent){
          //if parent is not null then by definition this node is a child node of the tree.
          return parent.getRootNode()
       }else{
          //if parent is null then by definition it is the root node.
          return this
       }
    }

    //you might not need this function, but ill add it as it is common in tree structures
    boolean isLeaf(){
       //determines if this node is a leaf node. a leaf is a node with zero childrens
       return children.isEmpty()
    }
}

As for ensuring that all treenodes is loaded, you can always use eager/non-lazy fetching for each treeNode both parent and children. Could however have a performance penalty if your tree structures are very large...

As for eager/lazy fetching. take a look here: Using lazy property fetching in Grails / Gorm

从此见与不见 2024-11-11 15:50:24

问题是级别填充了父树 id,但是当您加载树时,级别类会出现以下错误“找到具有给定标识符的多于一行”。

您的问题似乎是每棵树都有多个根节点。这是一种不寻常的方法。要使其正常工作,您必须将实体 Tree 中的 Level rootLevel 替换为 Set根。

The problem is that levels are filled with the parent Tree id, but when you load the Tree, you have the following error "More than one row with the given identifier was found" for the Level class.

Your problem seems to be that you have more than a single root node for each tree. This is an unusual approach. To make it work, you must replace Level rootLevel in the entity Tree with Set<Level> roots.

倦话 2024-11-11 15:50:24

我最终得到了这个解决方案(感谢一位朋友):

class Tree {
   String name
   Level rootLevel

   static hasMany = [levels: Level]
   static mappedBy = [rootLevel: "parentTree", levels: "owningTree"]

   static constraints = {rootLevel(nullable: true)}
}

并且

class Level {
   String name
   Tree parentTree
   Tree owningTree
   Level parentLevel
   Set<Level> subLevels

   static belongsTo = [owningTree: Tree, parentLevel: Level]
   static hasMany = [subLevels: Level]
   static mappedBy = [parentTree: "rootLevel", owningTree: "levels", subLevels: "parentLevel"]

   static constraints = {
       parentTree(nullable: true)
       parentLevel(nullable: true)
   }
}

我缺少树和级别(owningTree和parentTree)之间的两种关系以及一些有助于休眠的mappedBy配置。

I ended up with this solution (thanks to a friend):

class Tree {
   String name
   Level rootLevel

   static hasMany = [levels: Level]
   static mappedBy = [rootLevel: "parentTree", levels: "owningTree"]

   static constraints = {rootLevel(nullable: true)}
}

and

class Level {
   String name
   Tree parentTree
   Tree owningTree
   Level parentLevel
   Set<Level> subLevels

   static belongsTo = [owningTree: Tree, parentLevel: Level]
   static hasMany = [subLevels: Level]
   static mappedBy = [parentTree: "rootLevel", owningTree: "levels", subLevels: "parentLevel"]

   static constraints = {
       parentTree(nullable: true)
       parentLevel(nullable: true)
   }
}

I was missing the two relations between Tree and Level (owningTree and parentTree) and some mappedBy configuration to help hibernate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文