简体   繁体   English

Grails域创建关联表

[英]Grails Domain Create Association Table

I have a question about creating an associative table, in grails, to reconcile a many-to-many relationship. 我有一个问题,关于如何创建关联表以协调多对多关系。 The setup is this: 1. Domain A (Client Profile) can have many Domain B (Friends) 2. Each Domain B (Friends) can have many Domain A (Client Profile) 3. To Resolve this, I need to create an Associative table (or domain) that has FK's from each table. 设置是这样的:1.域A(客户配置文件)可以有多个域B(朋友)2.每个域B(朋友)可以具有许多域A(客户配置文件)3.要解决此问题,我需要创建一个关联每个表中都有FK的表(或域)。 This domain can be named Domain C (client_friend) 该域可以命名为域C(client_friend)

Here is the code I have so far: 这是我到目前为止的代码:

class DomainA{
    String id
String firstName
String lastName
    static hasMany = [domainB: DomainB]
    static mapping = {
    cache true
    id generator: 'assigned'

    columns {
        firstName   type:'text'
        lastName    type:'text'
        alumConnections column: 'domaina_id', joinTable: 'a_b'
    }

}
static constraints = {
    firstName   (nullable:true)
    lastName    (nullable:true)
}

  }

DomainB Code: DomainB代码:

   class DomainB{   
String id
String firstName
String lastName

    static hasMany = [domainA:DomainA]
static belongsTo = DomainA
static mapping = {
    cache true
    id generator: 'assigned'        

             columns {                  
        firstName       type:'text'
        lastName        type:'text'
        domainA column: 'domainb_id', joinTable: 'a_b'
    }
}
static constraints = {  
    firstName       (nullable:true)
    lastName        (nullable:true)

}
  }

Domain A_B code: 域A_B代码:

 class AB{


Date dateCreated
Date lastUpdated
long version

  }

When I run this code, it seems to work. 当我运行此代码时,它似乎可以工作。 The tables, using MySQL, are created, FK seem to be in place. 这些表是使用MySQL创建的,FK似乎已经到位。 When I enter data into the DomainB class, data is entered and both PK's from DomainA and DomainB are inserted into A_B. 当我在DomainB类中输入数据时,将输入数据,并将DomainA和DomainB的PK都插入到A_B中。 But, the problems comes when I try to delete values from A_B. 但是,当我尝试从A_B中删除值时,问题就来了。 I've tried something like this: 我已经尝试过这样的事情:

     AB results =AB.findByAIdAndBId('jIi-hRi4cI','2BYvuA2X14') 

but get an error: InvalidPropertyException: No property found for name [a_id] for class [class mgr.AB] 但收到错误:InvalidPropertyException:未找到类[class mgr.AB]的名称[a_id]的属性

My question is this: first, have i set this up correctly? 我的问题是:首先,我是否正确设置了? Second, if so, how then do i query the AB table who's PK is made up of a composite of DomainA and DomainB? 其次,如果是这样,那么我该如何查询AB表中谁的PK由DomainA和DomainB组成?

Thanks for any help. 谢谢你的帮助。

jason 杰森

Your composite class isn't entirely correct. 您的复合类并不完全正确。 Look at this example and adjust yours accordingly. 查看此示例,并相应地进行调整。 This is how I do all my composite domains: 这是我所有组合域的处理方式:

class UserRole implements Serializable {

    User user
    Role role

    boolean equals(other) {
        if (!(other instanceof UserRole)) {
            return false
        }

        other.user?.id == user?.id &&
            other.role?.id == role?.id
    }

    int hashCode() {
        def builder = new HashCodeBuilder()
        if (user) builder.append(user.id)
        if (role) builder.append(role.id)
        builder.toHashCode()
    }

    static UserRole get(long userId, long roleId) {
        find 'from UserRole where user.id=:userId and role.id=:roleId',
            [userId: userId, roleId: roleId]
    }

    static UserRole create(User user, Role role, boolean flush = false) {
        new UserRole(user: user, role: role).save(flush: flush, insert: true)
    }

    static boolean remove(User user, Role role, boolean flush = false) {
        UserRole instance = UserRole.findByUserAndRole(user, role)
        instance ? instance.delete(flush: flush) : false
    }

    static void removeAll(User user) {
        executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
    }

    static void removeAll(Role role) {
        executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
    }

    static mapping = {
        id composite: ['role', 'user']
        version false
    }
}

Once you have that, there is no need for the belongsTo and hasMany associations. 一旦有了这些,就不再需要belongsTo和hasMany关联。 But to access the data from those domains, you can provide methods like the following: 但是要访问这些域中的数据,您可以提供以下方法:

class User {

   // typical domain junk

   Set<Role> getAuthorities() {
     UserRole.findAllByUser(this).collect { it.role } as Set
   }
}

Then you can do things like userInstance.authorites just as if the hasMany was there. 然后,您可以执行诸如userInstance.authorites之类的事情,就像hasMany在那儿一样。 Basically, you're doing what Grails would typical do for you. 基本上,您正在做Grails通常为您做的事情。 But this is actually a good thing. 但这实际上是一件好事。 Collections in Grails can be costly if not done right. 如果处理不当,Grails中的收集可能会很昂贵。 This is being addressed in 2.0 with the use of Bags. 在2.0中,使用Bags可以解决此问题。

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

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