gpt4 book ai didi

Grails 多对多关联和防止级联

转载 作者:行者123 更新时间:2023-12-01 11:58:10 24 4
gpt4 key购买 nike

因此,我们在 Customer 和 Role 之间建立了多对多关系,设置为:

Customer {
static hasMany = [roles: Role]
}

Role {
static hasMany = [customer: Customer]
static belongsTo = Customer
}

角色对象只有一个名字和一组权限。我们不想从 Customer -> Role 级联保存,因为 Role 应该只直接修改。

我补充说:

static mapping = {
roles cascade: 'none'
}

但是,每当我创建一个客户时,角色表也会更新。没有任何变化,只是版本号增加了。

我是否遗漏了其他需要设置的东西...Grails 中设置的多对多关系和级联是否存在错误...或者是否有其他方法可以防止更新角色每次?

最佳答案

我通常将连接表映射为域类以避免此问题和其他问题(集合加载性能、乐观锁定错误等)。这涉及删除 hasManybelongsTo 并创建一个 CustomerRole 域类:

import org.apache.commons.lang.builder.HashCodeBuilder

class CustomerRole implements Serializable {

Customer customer
Role role

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

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

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

static CustomerRole get(long customerId, long roleId) {
find 'from CustomerRole where customer.id=:customerId and role.id=:roleId',
[customerId: customerId, roleId: roleId]
}

static CustomerRole create(Customer customer, Role role, boolean flush = false) {
new CustomerRole(customer: customer, role: role).save(flush: flush, insert: true)
}

static boolean remove(Customer customer, Role role, boolean flush = false) {
CustomerRole instance = CustomerRole.findByCustomerAndRole(customer, role)
instance ? instance.delete(flush: flush) : false
}

static void removeAll(Customer customer) {
executeUpdate 'DELETE FROM CustomerRole WHERE customer=:customer', [customer: customer]
}

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

static mapping = {
id composite: ['customer', 'role']
version false
table 'customer_roles'
}
}

映射 block 配置生成的 DDL,使其与您现在拥有的相同,因此您无需对数据库进行任何更改。静态辅助方法不是必需的,但可以方便地隐藏授予和撤销角色的过程。

您需要更改代码。由于没有 hasMany,您不能使用 customer.addToRoles(...)。要授予角色,只需使用 create 方法创建一个新的 CustomerRole 实例,而要撤销,请使用 remove 方法删除该实例。

更新后的 Role 类将是

class Role {
}

更新后的客户类将是

class Customer {
Set<Role> getRoles() {
CustomerRole.findAllByUser(this).collect { it.role } as Set
}
}

它有一个方便的方法 getRoles(),它模仿 hasMany 为您创建的 roles 集合,因为您仍然需要一个访问客户授予的角色的简单方法。

关于Grails 多对多关联和防止级联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4088810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com