Grails动态查找器很多

我有2个由多对多关系映射的域类。 我遵循Grails文档的说明,但在处理这些域上的数据时仍然遇到一些问题。 这里是我的2个领域类:

class User {
    String name
    int age
    String job
    static hasMany = [groups : Group]
    static belongsTo = [org : Organization]
}

class Group {
    String groupName
    String code
    static hasMany = [members : User]
}

我的问题是:
1.上述关系要求一个类别拥有belongsTo作为关系的“所有者”。 在这种情况下,用户属于Group,但我不知道如何将belongsTo设置为User类,因为Grails建议的标准语法是static belongsTo = [Group](只需指定所有者类名),所以我不能:
- 把它放到存在所属的地方就像这样:static belongsTo = [org:Organization,Group]
- 或者定义另一个belongsTo就像这样:static belongsTo = [Group]

  • 下面的例子是对的:

    class Book {String title static belongsTo =作者static hasMany = [作者:作者]

    static mapping = {
        authors joinTable:[name:"mm_author_books", key:'mm_book_id' ]
    }
    

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

    static mapping = {
        books joinTable:[name:"mm_author_books", key:'mm_author_id']
    }
    

    }

  • (引用链接:grails(GORM)/ hibernate中的多对多链接表)
    我的意思是,我们是否需要为每个类指定连接表的外键的名称?

  • 如果我想查找属于名称为“ABC”的指定组的成员的所有用户,那么如何使用Grails的DynamicFinder?
  • 非常感谢


    m2m关系非常罕见,所以我一直觉得奇怪的是必须指定一个让GORM正常工作。 正因为如此,我不这样做。 我将连接表创建为一个域。 然后事情变得非常简单。

    class UserGroup implements Serializable {
    
        User user
        Group group
    
        boolean equals(other) {
            if (!(other instanceof UserGroup)) {
                return false
            }
    
            other.user?.id == user?.id &&
                other.group?.id == group?.id
        }
    
        int hashCode() {
            def builder = new HashCodeBuilder()
            if (user) builder.append(user.id)
            if (group) builder.append(group.id)
            builder.toHashCode()
        }
    
        static UserGroup get(long userId, long groupId) {
            find 'from UserGroup where user.id=:userId and group.id=:groupId',
                [userId: userId, groupId: groupId]
        }
    
        static UserGroup create(User user, Group group, boolean flush = false) {
            new UserGroup(user: user, group: group).save(flush: flush, insert: true)
        }
    
        static boolean remove(User user, Group group, boolean flush = false) {
            UserGroup instance = UserGroup.findByUserAndGroup(user, group)
            instance ? instance.delete(flush: flush) : false
        }
    
        static void removeAll(User user) {
            executeUpdate 'DELETE FROM UserGroup WHERE user=:user', [user: user]
        }
    
        static void removeAll(Group group) {
            executeUpdate 'DELETE FROM UserGroup WHERE group=:group', [group: group]
        }
    
        static mapping = {
            id composite: ['group', 'user']
            version false
        }
    }
    

    然后你只需要在你的User和Group类中创建getter。 您将不会在任何一个班级中拥有User用户或Group组。 没有必要将它们与hasMany / belongsTo进行映射,因为所做的只是创建连接表,这通过创建UserGroup域来完成。

    class User {
       Set<Group> getGroups() {
        UserGroup.findAllByUser(this).collect { it.group } as Set
      }
    }
    
    class Group {
      Set<User> getUsers() {
        UserGroup.findAllByGroup(this).collect { it.user } as Set
      }
    }
    

    一旦你有了这些,你可以使用你在UserGroup域创建的方法和/或你可以使用它的发现者...

    def userGroupInstance = UserGroup.findByUserAndGroup(userInstance, groupInstance)
    def userGroups = UserGroup.findAllByUser(userInstance)
    def userGroupInstance = UserGroup.get(userId, groupId)
    

    你明白了。 Burt Beckwith的这个演示更清晰地说明了为什么这是一个很好的方法,以及一些其他的提高性能的重要技巧。


  • belongsTo将创建另一个M:1关系(字段) - 您告诉您的案例中是否有User的“主要组”。 如果我只希望强制执行至少一个组,那么我会使用User.groups的自定义验证程序检查它是否为空。

  • (我不确定) - 我相信是,如果密钥名称不同于默认的Hibernat / GORM“ userId ”/“ groupId ”。

  • findBy*()方法在这里不起作用,你需要一个CriteriaBuilder,就像这里。

  • 链接地址: http://www.djcxy.com/p/24331.html

    上一篇: Dynamic finders with Grails many

    下一篇: Child lazy get of child ids