【问题标题】:Grails Domain Create Association TableGrails 域创建关联表
【发布时间】:2011-10-20 07:35:17
【问题描述】:

我有一个关于在 grails 中创建关联表以协调多对多关系的问题。设置是这样的: 1. Domain A(Client Profile)可以有多个 Domain B(Friends) 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)
}

  }

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)

}
  }

域 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组成的?

感谢您的帮助。

杰森

【问题讨论】:

    标签: hibernate grails grails-domain-class grails-controller


    【解决方案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
       }
    }
    

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

    【讨论】:

    • 感谢您的回复。在我的示例中,DomainA 和 DomainB 怎么样?我需要摆脱他们的“属于”和“拥有很多”吗?
    • 是的,不需要它们。我将更新我的答案以反映如何处理。
    • 我实施了这些更改,似乎没问题。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多