将Sql查询转换为Grails / Gorm查询

时间:2019-07-03 15:33:15

标签: grails gorm

如何将以下SQL查询转换为Grails / Gorm?可以使用基本查询吗?我想避免使用Criteria,Projections和HQL使其与代码库中其他查询(基本查询)的结构保持一致。

  SELECT dealer_group_user_dealer_users_id, COUNT(user_id) 
    FROM db.dealer_group_user_user 
    GROUP BY dealer_group_user_dealer_users_id;

是否有可能在gsp页面中执行查询以显示特定user_id的结果,而不是在控制器中运行查询?

要从评论中进行更新,以下是我的域类。

class DealerGroupUser extends User{

   static hasMany = [dealerUsers: User]

   static constraints = {
   }
}


class User {
     transient authService

Boolean active = true
String firstName
String lastName
String title
String username
String emailAddress
String passwordHash
Date lastLoginTime
Date dateCreated
Date lastUpdated
Retailer dealer
Client client
Date passwordUpdated
Long dealerUser
Boolean isReadOnlyClientManager = false
String regionClientManager

// Transient properties
String fullName
String password

static transients = ['fullName', 'password']

static mapping = {
    //permissions fetch: 'join'
    sort firstName: 'asc' // TODO: Sort on fullName
}

static hasMany = [roles: Role, permissions: String]

static constraints = {
    // NOTE: If a username is not provided, the user's email address will be used
    firstName maxSize: 30, blank: false
    lastName maxSize: 30, blank: false
    title maxSize: 50, blank: false, nullable: true
    username blank: false, unique: true
    emailAddress email: true, unique: false, blank: false
    passwordHash blank: false
    lastLoginTime nullable: true
    active nullable: true
    dealer nullable: true
    client nullable: true
    passwordUpdated nullable: true
    dealerUser nullable: true
    regionClientManager nullable: true
}

void setEmailAddress(String emailAddress) {
    if (EmailValidator.instance.isValid(emailAddress)) {
        this.emailAddress = emailAddress
        if (!username) {
            username = emailAddress
        }
    }
}

static namedQueries = {
    dealerGroupUsers {
        eq 'class', 'com.db.torque.DealerGroupUser'
    }


}


Integer setPassword(String plainTextPassword) {
    plainTextPassword = plainTextPassword?.trim()
    if (plainTextPassword) {
        if (!plainTextPassword.matches("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\\S+\$).{8,}\$")){
            return -1
        }
        String previousPassword = this.passwordHash
        String newPassword = authService.encrypt(plainTextPassword)
        if (previousPassword != newPassword) {
            this.passwordHash = newPassword
            return 1
        }
        else {
            return -2
        }
    }
    return -1
}

@Transient
public static List<User> findAllByRolesContains(Role role) {
    return User.executeQuery("""
            SELECT u
            FROM User as u
            WHERE :role IN elements(u.roles)
        """, [role: role])
}

String fullName() {
    return "${firstName} ${lastName}"
}

String toString() {
    return fullName()
  }
}

1 个答案:

答案 0 :(得分:0)

  SELECT dealer_group_user_dealer_users_id, COUNT(user_id) 
    FROM db.dealer_group_user_user 
    GROUP BY dealer_group_user_dealer_users_id;

在您的用户类别中,您有:

Retailer dealer

因此,让我们从一开始就开始执行查询,从用户列表中列出用户,然后计算用户出现在Retailer域类上的次数吗?

做到这一点的最佳方法是

String query = """ select 
      new map(
              u.id as userId, 
              (select count(d) from DealerGroupUser d left join d.dealerUsers du where du=u) as userCount
      )
      From user u order by u.id
"""
def results = User.executeQuery(query,[:],[readOnly:true]

这应该按照我的想法做。

  

是否可以在gsp页面中执行查询以显示   特定user_id的结果,而不是在   控制器?

视图是presentation层,应该保留核心工作-如果需要使用TagLib调用。 控制器虽然在grails示例中使用,并且作为默认设置的一部分推出,但使事情变得更轻松,也不是最佳选择。您应该在serviceinjected并在controller中将其作为所需内容的实际模型的view中进行操作。

这是正确的方法-GSP具有运行时大小-保持简短,保持甜美