SQL / vues de bases de données en Grails

est-ce que quelqu'un sait quelle est la meilleure approche pour accéder à une vue sql à travers Grails (ou si c'est même possible)? Une façon évidente de le faire serait d'utiliser executeQuery contre la vue pour sélectionner une collection de lignes de la vue que nous ne traiterions pas comme une liste d'objets de domaine. Cependant, même dans ce cas, il n'est pas évident de savoir contre quelle classe de domaine exécuter executeQuery, puisque nous utilisons simplement cette classe de domaine pour exécuter la requête contre un entité complètement indépendante (la vue).

serait-il préférable de créer une classe de domaine représentant la vue et nous pourrions alors utiliser list() contre cette classe de domaine? Il semble qu'il y aurait des problèmes avec cela puisque Grails s'attend probablement à pouvoir insérer, mettre à jour, supprimer et modifier le schéma de table de n'importe quelle classe de domaine.

[Edit:

Question de suivi ici: classe de domaine Grails sans champ ID ou avec le champ composite partiellement nul

26
demandé sur Community 2009-01-08 21:17:48

3 réponses

vous pouvez utiliser le SQL simple dans les ombres qui est dans le cas d'accéder à une vue de la manière préférable (IMO):

par exemple dans votre contrôleur:

import groovy.sql.Sql

class MyFancySqlController {

    def dataSource // the Spring-Bean "dataSource" is auto-injected

    def list = {
        def db = new Sql(dataSource) // Create a new instance of groovy.sql.Sql with the DB of the Grails app

        def result = db.rows("SELECT foo, bar FROM my_view") // Perform the query

        [ result: result ] // return the results as model
    }

}

et la partie view:

<g:each in="${result}">
    <tr>
        <td>${it.foo}</td>
        <td>${it.bar}</td>
    </tr>
</g:each>

j'espère que la source est explicite. La Documentation peut être trouvée ici

34
répondu Siegfried Puchbauer 2009-01-08 18:38:29

vous pouvez mettre cela dans votre classe de domaine mappings:

static mapping = {
    cache 'read-only'
}

mais je ne suis pas sûr que ça aide les Hibernés à comprendre que c'est une vue... http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-cache-readonly

quoi qu'il en soit, nous utilisons beaucoup de vues de base de données comme classes de domaines grails dans notre projet actuel, parce que HQL est une douleur dans le cul et il est plus simple D'utiliser SQL pour joindre des tables.

une chose que vous devez être prudent sur cependant, est L'Hibernate batching des requêtes (et l'ensemble des affaires flush). Si vous insérez quelque chose dans une table, et puis dans la même transaction vous sélectionnez une vue qui dépend de cette table, vous n'obtiendrez pas les dernières lignes que vous avez insérées. Cela est dû au fait que Hibernate n'aura pas encore inséré les lignes, alors que si vous avez sélectionné la table dans laquelle vous avez inséré les lignes, Hibernate aurait compris qu'il devait vider ses requêtes en attente avant de vous donner le résultat de votre sélection.

une solution est de ( flush:true ) lors de la sauvegarde d'une instance de domaine que vous savez que vous aurez besoin de lire à travers une vue par la suite dans la même transaction.

ce serait cool cependant d'avoir une sorte de façon de dire à Hibernate qu'une vue/domaine dépend de quelles autres classes de domaine, de sorte que la chasse D'eau Hibernée fonctionne bien apparemment.

4
répondu Jason Plank 2011-11-21 18:03:34

Il est parfaitement possible de mapper un domaine classe à vue, juste le traiter comme une table ordinaire. Je pense que Grails va imprimer des messages de log sur le fait de ne pas pouvoir faire des inserts, des suppressions, etc. mais il ne lancera pas d'erreurs à moins que vous essayiez réellement de faire quelque chose d'autre que la requête avec la classe de domaine.

2
répondu Ben Williams 2009-01-09 11:01:54