Eine Sache, mit der ich heute gespielt habe, waren Many-to-Many-Beziehungen in Grails, um eine Tag Cloud zu erstellen. Um eine Tag Cloud zu erstellen, muss ich eine Reihe von Schlüssel/Wert-Paaren haben, jedes mit einer Bezeichnung und einem Wert der Bezeichnung, die wie folgt aussehen könnte:
['Java': 5, 'Grails': 16, 'Groovy': 12]
Aber um dies abzufragen, muss ich eine Many-to-Many-Beziehung abfragen und das obige Ergebnis erzeugen. In diesem Blog wird beschrieben, wie Sie dies mit HQL, Criteria und dem HibernateCriteriaBuilder erreichen.
Domain
Meine aktuelle Domain sieht wie folgt aus:
(In diesem Bild fehlt leider ein Tag-Attribut in der Klasse Snippet).
Wie Sie sehen können, kann ein Snippet mehrere Tags haben, während ein Tag zu mehreren Snippets gehören kann. Wie können wir dies abfragen?
Optionen
Wir haben in diesem Fall drei Möglichkeiten
- HQL
- Hibernate-Kriterien
- Hibernate-Kriterien mit dem HibernateCriteriaBuilder
HQL
Die HQL-Version ist nicht so schwer (und die anderen auch nicht), aber irgendwo müssen wir ja anfangen, also fangen wir mit dieser an.
Um am Ende zu beginnen: Die Abfrage sieht so aus:
select tag.text, count(snippet.id)
from Tag as tag
inner join tag.snippets as snippet
group by tag.text
Um diesen Code zu testen, finde ich es am einfachsten, die Grails-Konsole zu starten:
grails console
und führen Sie dort die HQL aus. Sie können dies tun, indem Sie die SessionFactory aus dem ApplicationContext abrufen. Dies geschieht durch den Zugriff auf die implizite Variable 'ctx' in der Konsole. Der vollständige Code sieht wie folgt aus:
def sessionFactory = ctx.sessionFactory
def session = sessionFactory.getCurrentSession()
def query = session.createQuery("select tag.text, count(snippet.id) from Tag as tag inner join tag.snippets as snippet group by tag.text")
def ergebnisse = abfrage.liste()
In meinem Fall ergibt das Folgendes (ich habe zwei Snippets, eines mit 3 Tags und eines mit 1 Tag, das ein Duplikat des ersten Snippets ist):
[["groovy", 1], ["io", 2], ["testing", 1]]
Hibernate Criteria
Da Grails auf Groovy/Java, Hibernate und Spring aufbaut, ist es einfach, diese Leistung zu nutzen, während Sie eine Lösung für Ihr Problem finden. Wenn Sie den ganzen Tag Java-Code schreiben und das Schreiben von Hibernate Criteria etwas ist, das Sie täglich tun, ist das überhaupt kein Problem. Kopieren Sie einfach Ihren bestehenden Java-Code und fügen Sie ihn in Grails ein, und Sie werden etwas wie dieses Ergebnis erhalten:
def sessionFactory = ctx.sessionFactory
def session = sessionFactory.getCurrentSession()
Liste Ergebnisse = session.createCriteria(Tag.class)
.setProjection ( Projections.projectionList()
.add (Projektionen.groupProperty("text"))
.add (Projektionen.rowCount() ) )
.createCriteria("Schnipsel")
.list()
Hibernate Criteria mit dem HibernateCriteriaBuilder Wenn Sie jedoch das Gefühl haben, dass die obige Darstellung nicht sehr elegant ist, sollten Sie sich den HibernateCriteriaBuilder ansehen, eine DSL für die Erstellung von Hibernate Criteria. Wenn Sie die DSL verwenden, müssen Sie zunächst den HibernateCriteriaBuilder abrufen, der von jeder Domänenklasse bezogen werden kann. Danach verfügen Sie über die volle Leistungsfähigkeit von Hibernate in einer einfachen, lesbaren DSL.
def c = Tag.createCriteria()
def Ergebnisse = c.Liste {
Projektionen {
groupProperty("text")
rowCount()
}
Schnipsel { }
}
Fazit
Wie Sie sehen, bietet Grails eine Vielzahl von Optionen zur Abfrage Ihrer Domäne. Ob Sie HQL, das sichere und solide Criteria oder den neuen HibernateCriteriaBuilder bevorzugen, bleibt Ihnen überlassen. Durch die Nutzung der Leistungsfähigkeit bestehender Frameworks bietet Grails eine einfache und leistungsstarke Möglichkeit, schnell eine Anwendung mit einer minimalen Lernkurve zu entwickeln!
Verfasst von
Erik Pragt
Contact



