6

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

考虑以下; 我有两个域类,一个 Author 和 Book 类,一个 Author 有很多书。

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)。我没有收到任何错误。这是我能想到的唯一方法,无需使用任何额外的对象,我想避免使用任何额外的对象来保持模型简单。我觉得我在正确的轨道上,但可能错过了一些重要的拼图。

任何帮助将非常感激。

4

3 回答 3

5

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

  1. Author作者写书,所以和之间存在一对多的关系Book。当然,在现实生活中,一本书可能由许多作者撰写,但在这种情况下,我们似乎可以忽略这一点。
  2. Author作者有最喜欢的书,因此和之间存在第二个多对多关系Book。这种关系是多对多的,因为一本书可能是许多作者的最爱。

所以假设我已经正确理解了这个问题,让我们试着找到一个解决方案。首先,让我们添加多对多关系(最喜欢的书):

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

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

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

static belongsTo = Author

Book类中,Book关系的拥有方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,而在我的模型中连接表将默认为author_favourites. 如果出于某种原因您特别希望连接表这样命名(例如,您试图将类映射到现有表),那么请随意包含上述内容。

最后,如果您发现自己在定义域类映射时遇到了困难,并且更愿意创建表,然后从它们生成域类,请查看这个插件

于 2013-04-17T00:40:43.170 回答
3

终于想通了。感谢 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]
}

再次感谢您的帮助

于 2013-04-18T22:50:30.153 回答
1

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

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

查找新表 FAVORITE_BOOKS 一次clean,然后run-app.

于 2013-04-17T00:23:15.057 回答