2009-07-31 5 views
3

J'ai une méthode de liste qui utilise HQL. comment ajouter les paramètres de pagination et de tri à cette requête?Grails: Ajout de tri et de pagination à une requête HQL personnalisée

def list = { 
     def termList 
     log.info "Getting terms for product: $params.productId" 
     params.max = 10 
     def p = Product.get(params.productId) 
     if (p) { 
      log.info "Product found: $p.name" 
      termList = Term.executeQuery("select distinct t from Term as t join t.definitions def join def.definitionProducts dp where dp.product=?", 
       p) 

     } else { 
      log.info "No Product found" 
      termList = Term.list(params) 

     } 
     log.info "Terms found: $termList.size" 

     [ termInstanceList: termList, termInstanceTotal: termList.size] 
    } 

Répondre

2

De la documentation:

// en utilisant avec carte des paramètres nommés et params de paginations (depuis 0,5) Account.executeQuery (« sélectionnez a.number distinct du compte où un a.branch =: branche ", [branch: 'London', max: 10, offset: 5]);

+0

Cette réponse n » t entièrement correct. Comme les états de réponse ci-dessous, vous ne pouvez pas obtenir le tri et l'ordre avec un executeQuery. Voir http://jira.codehaus.org/browse/GRAILS-1200. –

7

J'ai rencontré le même problème; alors que vous pouvez spécifier max et offset dans les paramètres executeQuery, le tri et l'ordre seront ignorés. Pour que cela fonctionne, j'ai dû spécifier le tri et l'ordre dans la requête HQL elle-même. La requête résultante devrait ressembler à:

"select distinct a.number from Account a where a.branch = :branch order by a.id asc" 

D'abord, dans vos colonnes triables vous devez modifier l'attribut de propriété pour faire référence au domaine que vous interrogez. Donc, pour "Compte a", faites ceci:

<g:sortableColumn property="a.id" title="Id"/> 

Ensuite, vous devrez modifier votre requête HQL. Malheureusement, il semble que vous ne puissiez pas utiliser les paramètres nommés dans la clause order by, vous devrez donc le faire manuellement. Ce serait probablement une bonne idée de désinfecter params.order et params.sort en premier.

"select distinct a.number from Account a where a.branch = :branch order by " + params.sort + " " params.order 

Cela a fonctionné pour moi, j'espère vraiment qu'il y a un meilleur moyen de sortir.

+0

En HQL, je pense que vous devez inclure spécifiquement la clause order dans la requête. Je pense que le tri en utilisant le paramètre de tri habituel ne fonctionnera pas. Max et offset devraient être utilisés pour la pagination. Voir les exemples http://grails.asia/grails-tutorial-for-beginners-hql-queries – JavaDev

3

Soyez prudent lorsque vous ajoutez des paramètres non valides à une requête SQL.

je validation comme ceci:

params.sort = 
    params.sort in ['id','name'] ? params.sort:'name' 
params.order = 
    params.order in ['asc','desc'] ? params.order:'asc' 

Ensuite, je peux en toute sécurité ajouter les paramètres à ma requête SQL

String sql = """ 
    SELECT NEW MAP(c.id as id, c.name as name) FROM Customer c 
    WHERE c.partner.id = :id 
    ORDER BY c.$params.sort $params.order 
""".stripMargin() 

Et enfin courir le executeQuery

def customers = Customer.executeQuery(
    sql, 
    [id:params.long('id')], 
    [max:params.long('max'),offset:params.long('offset')] 
) 
+1

Si vous avez beaucoup de paramètres, une belle façon de vérifier le paramètre de tri est d'utiliser: 'params.sort = new Customer() .domainClass.persistentProperties * .name.contains (params.sort)? params.sort: 'nom' – Cookalino

Questions connexes