1

我有一个关于在 grails 中创建关联表以协调多对多关系的问题。设置是这样的: 1. 域 A(客户端配置文件)可以有多个域 B(朋友) 2. 每个域 B(朋友)可以有多个域 A(客户端配置文件) 3. 为了解决这个问题,我需要创建一个关联具有来自每个表的 FK 的表(或域)。此域可以命名为域 C (client_friend)

这是我到目前为止的代码:

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)
}

  }

域B代码:

   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)

}
  }

域 A_B 代码:

 class AB{


Date dateCreated
Date lastUpdated
long version

  }

当我运行这段代码时,它似乎工作。创建了使用 MySQL 的表,FK 似乎就位。当我在 DomainB 类中输入数据时,数据被输入,并且来自 DomainA 和 DomainB 的 PK 都被插入到 A_B 中。但是,当我尝试从 A_B 中删除值时,问题就来了。我试过这样的事情:

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

但得到一个错误: InvalidPropertyException: No property found for name [a_id] for class [class mgr.AB]

我的问题是:首先,我设置正确了吗?其次,如果是这样,那么我如何查询AB表谁的PK是由DomainA和DomainB组成的?

谢谢你的帮助。

杰森

4

1 回答 1

1

您的复合类并不完全正确。查看此示例并相应地调整您的示例。这就是我处理所有复合域的方式:

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
    }
}

一旦你有了它,就不需要 belongsTo 和 hasMany 关联。但是要访问这些域中的数据,您可以提供如下方法:

class User {

   // typical domain junk

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

然后,您可以执行 userInstance.authorites 之类的操作,就像 hasMany 在那里一样。基本上,您正在做 Grails 通常会为您做的事情。但这实际上是一件好事。如果操作不当,Grails 中的集合可能代价高昂。2.0 中正在使用 Bags 解决这个问题。

于 2011-08-04T21:00:05.500 回答