[英]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有两个主要考虑因素:
更新:
我还想澄清一下,当你使用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.