Java Grails:GORM:遍历多对多关系
我有两个域对象,User和SystemRights(这是一个多对多的对象,因此一个用户可以拥有多个权限,一个权限可以由多个用户拥有)。我正在寻找一种简单的方法来检查用户是否拥有所需的权限 用户域Java Grails:GORM:遍历多对多关系,java,hibernate,grails,many-to-many,gorm,Java,Hibernate,Grails,Many To Many,Gorm,我有两个域对象,User和SystemRights(这是一个多对多的对象,因此一个用户可以拥有多个权限,一个权限可以由多个用户拥有)。我正在寻找一种简单的方法来检查用户是否拥有所需的权限 用户域 class User { static hasMany = [systemRights: SystemRight, enterpriseUsers: EnterpriseUser] String email; String passwordHash; } class
class User {
static hasMany = [systemRights: SystemRight, enterpriseUsers: EnterpriseUser]
String email;
String passwordHash;
}
class SystemRight {
public static final String LOGIN = "LOGIN"
public static final String MODIFY_ALL_ENTERPRISES = "MODIFY_ALL_ENTERPRISES"
public static final String ADMINISTER_SYSTEM = "ADMINISTER_SYSTEM"
public static final String VALIDATE_SUPPLIER_SCORECARDS = "VALIDATE_SUPPLIER_SCORECARDS"
static hasMany = [users:User]
static belongsTo = User
String name
}
public boolean hasRights(List<String> requiredRights) {
for (String requiredRight : requiredRights) {
def has = false
for (SystemRight userRight : user.systemRights) {
if (userRight.name == requiredRight) {
has = true
break;
}
}
if (has == false) {
return false;
}
}
return true
}
SystemRight域
class User {
static hasMany = [systemRights: SystemRight, enterpriseUsers: EnterpriseUser]
String email;
String passwordHash;
}
class SystemRight {
public static final String LOGIN = "LOGIN"
public static final String MODIFY_ALL_ENTERPRISES = "MODIFY_ALL_ENTERPRISES"
public static final String ADMINISTER_SYSTEM = "ADMINISTER_SYSTEM"
public static final String VALIDATE_SUPPLIER_SCORECARDS = "VALIDATE_SUPPLIER_SCORECARDS"
static hasMany = [users:User]
static belongsTo = User
String name
}
public boolean hasRights(List<String> requiredRights) {
for (String requiredRight : requiredRights) {
def has = false
for (SystemRight userRight : user.systemRights) {
if (userRight.name == requiredRight) {
has = true
break;
}
}
if (has == false) {
return false;
}
}
return true
}
以下内容对我不起作用:
在User.class中
public boolean hasRights(List<String> requiredRights) {
def userHasRight = SystemRight.findByUserAndSystemRight (this, SystemRight.findByName(requiredRight));
// Nor this
def userHasRight = this.systemRights.contains(SystemRight.findByName(requiredRight));
}
public boolean权限(列出所需权限){
def userHasRight=SystemRight.findByUserAndSystemRight(这是SystemRight.findByName(requiredRight));
//也不是这个
def userHasRight=this.systemRights.contains(SystemRight.findByName(requiredRight));
}
当前可怕的解决方案
class User {
static hasMany = [systemRights: SystemRight, enterpriseUsers: EnterpriseUser]
String email;
String passwordHash;
}
class SystemRight {
public static final String LOGIN = "LOGIN"
public static final String MODIFY_ALL_ENTERPRISES = "MODIFY_ALL_ENTERPRISES"
public static final String ADMINISTER_SYSTEM = "ADMINISTER_SYSTEM"
public static final String VALIDATE_SUPPLIER_SCORECARDS = "VALIDATE_SUPPLIER_SCORECARDS"
static hasMany = [users:User]
static belongsTo = User
String name
}
public boolean hasRights(List<String> requiredRights) {
for (String requiredRight : requiredRights) {
def has = false
for (SystemRight userRight : user.systemRights) {
if (userRight.name == requiredRight) {
has = true
break;
}
}
if (has == false) {
return false;
}
}
return true
}
public boolean权限(列出所需权限){
for(字符串requiredRight:requiredRights){
def has=false
for(SystemRight userRight:user.systemRights){
if(userRight.name==requiredRight){
has=true
打破
}
}
如果(has==false){
返回false;
}
}
返回真值
}
如果你能够/愿意改变一些事情,我强烈建议你做以下几点。这会让你的生活轻松很多
首先,从这两个域中删除hasMany for SystemRight和User,并从SystemRight中删除belongsTo User
接下来,创建表示联接表的域
class UserSystemRight {
User user
SystemRight systemRight
boolean equals(other) {
if (!(other instanceof UserSystemRight)) {
return false
}
other.user?.id == user?.id && other.systemRight?.id == systemRight?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (systemRight) builder.append(systemRight.id)
builder.toHashCode()
}
// add some more convenience methods here if you want like...
static UserSystemRight get(long userId, long systemRightId, String systemRightName) {
find 'from UserSystemRight where user.id=:userId and systemRight.id=:systemRightId and systemRight.name=:systemRightName',
[userId: userId, systemRightId: systemRightId, systemRightName: systemRightName]
}
}
然后,在用户类中可以添加以下方法:
Set<SystemRight> getSystemRights() {
UserSystemRight.findAllByUser(this).collect { it.systemRight } as Set
}
Set getSystemRights(){
UserSystemRight.findallbyser(this).collect{it.systemRight}作为集合
}
然后,将其添加到SystemRight域:
Set<User> getUsers() {
UserSystemRight.findAllBySystemRight(this).collect { it.user } as Set
}
Set getUsers(){
UserSystemRight.findAllBySystemRight(this).collect{it.user}作为集合
}
要更详细地解释为什么这种方法除了实际解决您的问题外,还充满了胜利。如果您能够/愿意改变一些事情,我强烈建议您执行以下操作。这会让你的生活轻松很多 首先,从这两个域中删除hasMany for SystemRight和User,并从SystemRight中删除belongsTo User 接下来,创建表示联接表的域
class UserSystemRight {
User user
SystemRight systemRight
boolean equals(other) {
if (!(other instanceof UserSystemRight)) {
return false
}
other.user?.id == user?.id && other.systemRight?.id == systemRight?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (systemRight) builder.append(systemRight.id)
builder.toHashCode()
}
// add some more convenience methods here if you want like...
static UserSystemRight get(long userId, long systemRightId, String systemRightName) {
find 'from UserSystemRight where user.id=:userId and systemRight.id=:systemRightId and systemRight.name=:systemRightName',
[userId: userId, systemRightId: systemRightId, systemRightName: systemRightName]
}
}
然后,在用户类中可以添加以下方法:
Set<SystemRight> getSystemRights() {
UserSystemRight.findAllByUser(this).collect { it.systemRight } as Set
}
Set getSystemRights(){
UserSystemRight.findallbyser(this).collect{it.systemRight}作为集合
}
然后,将其添加到SystemRight域:
Set<User> getUsers() {
UserSystemRight.findAllBySystemRight(this).collect { it.user } as Set
}
Set getUsers(){
UserSystemRight.findAllBySystemRight(this).collect{it.user}作为集合
}
要更详细地解释为什么这种方法除了实际解决您的问题外,还充满了胜利,请看下面的内容
public boolean hasRights(List<String> requiredRights) {
return null != (this.systemRights.find { requiredRights.contains(it) });
}
public boolean权限(列出所需权限){
返回null!=(this.systemRights.find{requiredRights.contains(it)});
}
(未经测试:这里是Groovy新手)以下内容如何
public boolean hasRights(List<String> requiredRights) {
return null != (this.systemRights.find { requiredRights.contains(it) });
}
public boolean权限(列出所需权限){
返回null!=(this.systemRights.find{requiredRights.contains(it)});
}
(未测试:这里是Groovy newbie)我一定会尝试在数据库中解决这个问题
def relevantUserRights = SystemRight.withCriteria {
eq("user", this)
"in"("name", requiredRights);
}
return relevantUserRights.size() == requiredRights.size()
我一定会在数据库中解决这个问题
def relevantUserRights = SystemRight.withCriteria {
eq("user", this)
"in"("name", requiredRights);
}
return relevantUserRights.size() == requiredRights.size()
嗨,格雷格,谢谢你的回答。你是在建议失去多对多的关系吗。由于这些限制,我对User和Enterprise以及UserEnterprise这样做了。如果这是你的建议,那么我想我会终止我项目中所有的m2m关系。它仍然是m2m,你只是自己管理联接表。嗨,Gregg,谢谢你的回答。你是在建议失去多对多的关系吗。由于这些限制,我对User和Enterprise以及UserEnterprise这样做了。如果这是你的建议,那么我想我将终止我项目中的所有m2m关系。它仍然是m2m,你只是自己管理联接表。我完全喜欢null!=戏法以前从没想过!我完全喜欢空的戏法以前从没想过+谢谢你。我对此进行了测试,效果良好,但我决定使用@Gregg的答案并重构我的域对象来创建一个显式连接表。+1谢谢。我对此进行了测试,结果很有效,但我决定使用@Gregg的答案并重构我的域对象来创建一个显式连接表。