Конвертировать Sql Query в Grails / Gorm запрос - PullRequest
0 голосов
/ 03 июля 2019

Как мне преобразовать следующий SQL-запрос в Grails / Gorm? Можно ли это сделать с помощью основного запроса? Я хотел бы избежать использования критериев, проекций и 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 голосов
/ 03 июля 2019
  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 и используются по умолчанию, чтобы упростить работу, также не лучшее место. Вы должны делать это в service, который равен injected в controller и представлен в view как фактическая модель того, что необходимо.

Это правильный путь - у GSP есть размер среды выполнения - оставьте его коротким, оставьте его сладким

...