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

Grails:两个域对象之间的多个关系,grails,gorm,Grails,Gorm,我试图在Grails中的两个域类之间实现两种不同类型的关系 考虑以下几点:;我有两个域类,一个是Author类,另一个是Book类,其中一个Author有很多书 class Author{ String name } class Book{ String title static belongsTo = [author:Author] } 以上描述了作者和一本书之间非常基本的一对多关系。 但我也希望一个作家有一个最喜欢的书列表的概念。理想情况下,这

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

考虑以下几点:;我有两个域类,一个是Author类,另一个是Book类,其中一个Author有很多书

class Author{           
   String name 
}

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

}
以上描述了作者和一本书之间非常基本的一对多关系。 但我也希望一个作家有一个最喜欢的书列表的概念。理想情况下,这将表示为一个单独的一对多关系,将同一图书对象描述为一个列表,并作为列表进行持久化

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]

}
我试着如上所述(在许多其他方法中)描述这一点,但最终并没有创建数据库表(Favorite_books)。我没有得到任何错误。这是我能想到的唯一方法,不用使用任何额外的对象,我希望避免使用这些对象来保持模型的简单。 我觉得我在正确的轨道上,但可能错过了一些重要的拼图


任何帮助都将不胜感激。

修改
Book
域类。删除
作者
映射

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

查找新表中最喜爱的书籍一次
clean
runapp

首先,让我们确保我正确理解您的问题。您有
Book
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']
    }
    
    这将导致将联接表命名为
    收藏夹
    ,而在我的模型中,联接表将默认为
    作者收藏夹
    。如果出于某种原因,您特别希望联接表的命名如下(例如,您正试图将类映射到现有表),那么可以随意包含上述内容

    最后,如果您发现自己在定义域类映射方面遇到了困难,并且更习惯于创建表,然后从表中生成域类,请查看

    最终解决了这个问题。 感谢Don为我指明了db反向工程插件的方向,该插件帮助我公开了支持这种映射策略的关键属性。 基本上,这一切都归结为使用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]
    }
    

    再次感谢您的帮助

    您是否尝试过清理、退出、再次使用grails,然后运行应用程序。有时grails在没有
    clean
    的情况下无法获取您的域更改。在上面的第一个示例中,您缺少
    Author
    端的
    hasMany
    属性,在第二个示例中,
    Book
    端没有引用
    收藏夹书籍的关系。感谢您提供的快速详细信息答复。你对我试图实现的目标的理解是正确的,虽然它有效,但我似乎对这种方法有一个小问题。我似乎最终得到了一个单独的author\u books\u writed表来映射作者对一本书的所有权。我只是希望在我的书桌上有一个作者id?有可能绕过这个问题吗?顺便说一下,我们可以假设一本书只能有一位作者。
    
    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]
    }