Grails:两个域对象之间的多个关系

时间:2013-04-16 23:02:29

标签: grails gorm

我正在尝试在Grails中的两个域类之间实现两种不同类型的关系。

考虑以下事项;我有两个域类,一个作者和书类,作者有很多书。

class Author{           
   String name 
}

class Book{
   String title
   static belongsTo = [author:Author]

}

以上描述了作者和书之间非常基本的一对多关系。 但我也希望作者有一个喜欢的书籍列表的概念。理想情况下,这将表示为一个单独的一对多关系,将同一个Book对象描述为一个列表并保持原样。

class Author{          
   String name
   static hasMany = [favouriteBooks: Book]

   static mapping = {
        favouriteBooks joinTable: [name: 'favourite_books',
                key: 'author_id']
   }
}

class Book{
   String title
   static belongsTo = [client:Client]

}

我试图在上面描述这个(在许多其他方法中)并且最终没有创建数据库表(favourite_books)。我没有得到任何错误。这是我能想到的唯一方法,不使用任何额外的对象,我希望避免使模型保持简单。 我觉得自己走在了正确的轨道上,但也许错过了一些重要的难题。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

首先,让我们确保正确理解您的问题。您有BookAuthor个域类,但这些类之间有两个关系:

  1. 作者撰写书籍,因此AuthorBook之间存在一对多的关系。当然,在现实生活中,许多作者可能会写一本书,但在这种情况下,我们可以忽略这一点。
  2. 作者有最喜欢的书籍,因此AuthorBook之间存在第二个多对多关系。这种关系是多对多的,因为一本特定的书可能是许多作者的最爱。
  3. 因此,假设我已正确理解问题,让我们尝试找到解决方案。首先,让我们添加多对多关系(最喜欢的书籍):

    class Author {
        String name
        static hasMany = [favourites: Book]
    }
    
    class Book {
        String title
        static hasMany = [favouritedBy: Author]
        static belongsTo = Author
    }
    

    每当定义多对多关系时,我们必须选择一方作为关系的所有者。在这种情况下,我已经指定了

    static belongsTo = Author
    
    <{1>}类中的

    ,因此Book是关系的拥有方,Book是所有者。因此,我们应该将最喜欢的书籍添加到作者而不是反之亦然,see here以获取更多详细信息。

    然后可以添加一对多关系:

    Author

    顺便说一下,在您的域模型中,您在class Author { String name static hasMany = [favourites: Book, booksWritten: Book] } class Book { String title static hasMany = [favouritedBy: Author] static belongsTo = Author Book writtenBy }

    中包含了以下内容
    Author

    这将导致联接表被命名为static mapping = { favouriteBooks joinTable: [name: 'favourite_books', key: 'author_id'] } ,而在我的模型中,联接表将默认为favourite_books。如果由于某种原因您特别想要将连接表命名为这样(例如,您尝试将类映射到现有表),那么可以随意包含上述内容。

    最后,如果您发现自己正在努力定义域类映射,并且更适合创建表,然后从中生成域类,请查看this plugin

答案 1 :(得分:2)

终于弄明白了。 感谢Don让我指向db-reverse-engineer插件的方向,这有助于公开允许这种映射策略的关键属性。 基本上,所有这些都归结为使用GORM的mappedBy关联设置来明确告诉Grails如何映射多个hasMany引用。 有效的类文件如下:

class Author {

    String name
    static hasMany = [books: Book, favourites: Book]

    // need to disambiguate the multiple hasMany references with the 
    // 'mappedBy' property:
    static mappedBy =   [books: "author",
                        favourites: "authors"]
}

class Book {

    String title
    Author author

    static hasMany = [authors: Author]
    static belongsTo = [Author]
}

再次感谢您的帮助

答案 2 :(得分:1)

修改Book域类。删除author映射。

class Book{
   String title
   static belongsTo = [Author]
}

cleanrun-app后查找新表格FA​​VORITE_BOOK。