Allgemein
- Abfragen gegen JDBC Content Stores werden in HQL (Hibernate Query
Language) formuliert, der integrierten Abfragesprache von Hibernate,
einer Software die zwischen den Objekten in WGA (Content-Dokumente,
Struktureinträge etc.) und den relational gespeicherten Daten
vermittelt. Eine umfangreiche Dokumentation zu HQL finden sie im Netz:
Es gibt einen einzigen Unterschied zwischen den hier gezeigten
Abfragen und jenen, die sie in WGA verwenden. HQL-Queries beginnen
normalerweise mit einer Beschreibung des Objekttypen, der ermittelt
werden soll, z.B.
from WGContent as content where ....
Da in WGA-Queries immer derselbe Objekttyp gesucht wird, nämlich Content-Dokumente, übernimmt WGA diesen Teil. Das was in WGA-Queries formuliert wird ist nur der Teil hinter dem where:<tml:query type="hql">content.uniquename = 'home'</tml:query>
Muss die gesamte HQL-Query formuliert werden (was in einigen Spezialfällen notwendig sein kann) so kann man den Querytypen als "fullhql" anstelle "hql" angeben. Hierbei wird dann eine komplette valide Hibernate-HQL-Abfrage als Eingabe erwartet.
<tml:query type="fullhql">from WGContent as content where content.uniquename = 'home'</tml:query>
Generelle Syntax
- Die Syntax von HQL ist objektorientiert. Man operiert an
Objekten und deren Eigenschaftswerten, die Text-, Nummer- oder
Datumswerte sein können oder wiederum selbst Objekte mit eigenen
Eigenschaftswerten.
Basis einer Query in WGA ist immer das Objekt content. Fragt man eine Eigenschaft des Objektes content ab, so stellt man sie mit einem Punkt dem Objektnamen hinten an:
content.title = 'Home'
Bestimmte Eigenschaften von Objekten sind wiederum selbst Objekte
mit eigenen Eigenschaften. Will man die Eigenschaften dieser Objekte
abfragen, stellt man sie wiederum mit einem Punkt hinten an:
content.language.name = 'de'
Hier wird die Eigenschaft language des Objektes content
abgefragt. Da diese Eigenschaft selbst wieder ein Objekt (vom Typ
Language) ist, können dessen Eigenschaften, wie name in diesem
Beispiel, durch Anfügen eines weiteren Punktes abgefragt werden.
Die verfügbaren Objekte und Eigenschaften der Objekte in WGA sind im Anhang dieses Dokumentes dokumentiert.
ACHTUNG: Wenn auf Schlüsselnamen von Objekten (z.B. der Name von Sprachdefinitionen, wie in diesem Beispiel) geprüft wird, so müssen diese immer im Lower-Case angegeben werden. Die Schlüsselnamen sind in der Referenz "Objekte in HQL-Abfragen und ihre Eigenschaften" am Ende dieses Kapitels als solche ausgewiesen.
Umgang mit Listeneigenschaften
Bestimmte Eigenschaften bestehen aus Listen von Werten, die entweder mit einer Nummer oder einem Textbezeichner indiziert sind. Will man eines der Listenelemente einzeln adressieren, so setzt man den Index in eckige Klammern dem Bezeichner hinten an:
content.items['Body'].text != ''
VORSICHT: Die Indizes sind Gross/Klein-Sensitiv!
Alle Listeneigenschaften haben selbst wiederum die Eigenschaft size, mit welcher Anzahl der Listenelemente geprüft werden kann:
content.items.size > 10
- minIndex und maxIndex: Minimaler und maximaler Index.
- minElement und maxElement: Kleinstes und grösstes Element aller Listenelemente (NICHT die Elemente am kleinsten und grössten Index!), wenn die Listenelemente selbst keine Objekte sind.
Diese Eigenschaften funktionieren jedoch nicht auf Datenbanksystemen, die keine Subqueries unterstützen (wie z.B. MySQL 4.0).
Allgemeine Operatoren
Allgemeine Operatoren sind solche Operatoren, die nicht in Abhängigkeit zu einer speziellen Funktion stehen, sondern generell überall verwendet werden können.
Mehrere Ausdrücke können mit Operatoren verbunden werden, wie sie in SQL üblich sind:
content.title = 'Home' AND content.language.name = 'de'
content.title = 'Home' OR content.language.name = 'de'
content.title = 'Home' AND NOT content.language.name = 'en'
content.title = 'Home' AND
(content.language.name = 'en' OR content.language.name = 'de')
content.virtuallink is not null
content.structentry.position != 0
content.structentry.position > 0
content.structentry.position >= 0
content.title like '%wga%'
content.structentry.doctype.name in ('Standard', 'Homepage', 'News')
content.structentry.position between 0 and 10
exists content.items['body']
Es ist möglich, HQL eine Sortierung der Ergebnisse vorzugeben. Das ist in aller Regel performanter, als die (nachträgliche) Sortierung per WebTML. Dazu muss dem Selektionsausdruck (wenn vorhanden) eine order by-Klausel angefügt werden:
order by content.title, content.created
ACHTUNG: Sortierungen sind in HQL leider nur nach Metadaten-Feldern, jedoch nicht nach Items möglich.
Items in der JDBC Content Store
- Es werden zwei Subqueries formuliert, jeweils eine in jeder Klammer die separat von der Hauptabfrage ausgeführt werden
- In jeder Subquery werden direkt ContentItem-Objekte abgefragt, welche den gewünschten Namen und den gewünschten Inhalt haben sollen
- Jede Subquery gibt als Ergebnis die Content-Objekte zurück, zu welchen die selektierten Items gehören
- Das Konstrukt "content in" sorgt dafür, dass in der Hauptabfrage nur Contents selektiert werden die durch die jeweilige Subquery zurückgegeben wurden
- Durch AND-Verknüpfung wird dafür gesorgt, dass das Endergebnis der Hauptabfrage nur Contents enthält, die durch alle Subqueries zurückgegeben wurden
Items sind in HQL eigene Objekte, die in der Listeneigenschaft items des Content-Objektes gespeichert sind. Diese Listeneigenschaft ist mit den Namen der Items indiziert:
content.items['body']
content.items['body'].text
content.items['body'].number
content.items['body'].date
ACHTUNG: In HQL können nur Items abgefragt werden, die keine Mehrfachwerte enthalten!
Items können wie oben beschrieben auf bestimmte Werte überprüft werden.
content.items['type'].text = 'article'
content.items['count'].number = 5
content.items['startdate'].date > '2005-05-01 10:00:01.0'
content.items['type'].text = 'article' AND content.items['count'].number = 5 FUNKTIONIERT NICHT!
Grund hierfür ist die Tatsache, dass Items und die sonstigen Daten von Contentdokumenten sich in separaten Tabellen befinden. Einen (komplizierteren) Ausweg aus dieser Situation biete das Artefakt der Subqueries. Ist der Datenbankserver in der Lage SQL-Subqueries zu interpretieren so können AND-verknüpfte Item-Abfragen folgendermaßen formuliert werden:
content in (select item.parentcontent from ContentItem as item where item.name='type' and item.text='article') AND
content in (select item.parentcontent from ContentItem as item where item.name='count' and number=5)
Funktionen
- Funktionen haben einen Funktionsnamen und übernehmen in runden Klammern Parameter.
Eine Funktion, die Tests gegen alle Elemente einer Liste erlaubt, ist elements.
'Hamburg' in elements(content.keywords)
In Kombination mit dem in-Operator kann man so gegen alle Werte eines Items testen.
Ein weiterer Operator, der in Zusammenhang mit elements benutzt werden kann, ist all. Er testet, ob alle von Elemente einer Liste demselben Wert entsprechen:
nav = all elements(content.ishiddenfrom)
Die Funktionen upper und lower erlauben die Manipulation von Strings, so dass diese nur aus Gross- bzw. Kleinbuchstaben bestehen:
upper(content.title) like %HAMBURG%
en Datenbank-Server unterstützt werden, in HQL zu integrieren. So kann z.B. die MySQL-Funktion date_sub auch in HQL verwendet werden, wenn als Datenbank-Backend ein MySQL-Server fungiert:
content.lastmodified < date_sub(NOW(), INTERVAL 10 DAY)

