繁体   English   中英

什么时候应该使用grails域类中的N:1关系?

[英]When should hasMany be used for N:1 relationships in grails domain classes?

在grails中,我可以实现这样的N:1关系:

class Parent { hasMany = [children:Child] }
class Child  { belongsTo = [parent:Parent] }

现在(如果总是正确使用addTo和removeFrom)我可以通过parent.children获取Parent的子项。

但我也可以在没有hasMany的情况下做到这一点:

class Parent { }
class Child  { belongsTo = [parent:Parent] }

然后我必须使用Child.findAllByParent(父)来获取所有孩子。

我的问题:如果能以第二种方式查询父母的孩子,我有什么理由可以使用hasMany吗?

我想它有时更容易(也许更快,如果与父母一起渴望获取?)只是引用parent.children,但另一方面,当有几个孩子时,这个List会变得相当长。 而我不喜欢的事情还有很多,你总是需要注意addTo或removeFrom,或者在添加一个带有Parent的新Child之后清除会话,以便grails自动执行此操作...

答案是你应该简单地使用hasMany如果有很少的孩子并且如果有很多孩子而不使用它(出于性能原因),或者还有更多的孩子?

使用hasMany与belongsTo更相关的是在更新/删除发生时要指定的级联行为。 在第二个示例中,级联在子端设置为ALL,在父端设置为NONE。 如果删除子项,则父项不会发生任何事情。 如果删除父项,则会自动删除所有子项。

在您的第一个示例中,级联在父级设置为ALL,在子级端设置为SAVE-UPDATE。 所以现在你可以这样做:

parent.addToChildren(child1)
parent.addToChildren(child2)
parent.addToChildren(child3)
parent.save(flush:true)

当您保存父母时,所有孩子都将被更新。

触摸你没有问过的东西,你可能也有类似的东西:

class Parent { hasMany = [children:Child] }
class Child  { Parent parent }

如果以这种方式定义从Child到Parent的关系,则需要在删除父*时手动管理引用父对象的Child对象。 (*这纠正了之前证明不准确的陈述)

因此,hasMany / belongsTo有两个主要考虑因素:

  1. 您希望在更新/删除时执行什么样的级联策略
  2. 如果您希望为父项检索一组子项,那么您最有可能访问数据,拥有parent.getChildren()方法非常方便。

更新:

我还想澄清一下,当你使用hasMany时,GORM不会急于获取; 默认情况下,GORM使用延迟提取策略,因此在尝试访问parent.children之前,它不会获取子进程

如果希望默认情况下急切地获取关联,则可以指定适当的映射:

class Parent { 
  hasMany = [children:Child]
  static mapping = {
    children lazy:false
  }
}

最后,你提到你不喜欢你必须担心hasMany方面的addTo / removeFrom。 如果使用flush:true保存,则不必执行此操作。

def parent = Parent.get(id)
def child = new Child(name:'child1', parent:parent)
if(child.save(flush:true)) {
  // both sides of the relationship should be good now
} 

编辑:修复了子/父级联默认的逆序并纠正了关于gorm如何处理没有belongsTo的关系的错误观念

很好的问题,目前接受的答案是好的。 还有一个重要的性能考虑因素,即添加和保存新孩子时会发生的情况。 在第一个示例中,默认情况下,Grails必须在将新的子项插入Set之前从数据库中加载整个子项列表,以保证唯一性。 在第二种情况下,它没有,这导致更好的性能。 您可以在第一个示例中通过根据http://grails.org/doc/latest/guide/single.html#sets,ListsAndMaps将子项定义为“集合”来解决此问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM