Hibernate.org Community Documentation

- Zurück
- Weiter

## Kapitel 16. HQL: Die "Hibernate Query Language"

Hibernate uses a powerful query language (HQL) that is similar in appearance to SQL. Compared with SQL, however, HQL is fully object-oriented and understands notions like inheritance, polymorphism and association.

## 16.1. Beachtung der Groß- und Kleinschreibung

With the exception of names of Java classes and properties, queries are case-insensitive. So `SeLeCT` is the same as `sELEct` is the same as `SELECT`, but `org.hibernate.eg.FOO` is not `org.hibernate.eg.Foo`, and `foo.barSet` is not `foo.BARSET`.

This manual uses lowercase HQL keywords. Some users find queries with uppercase keywords more readable, but this convention is unsuitable for queries embedded in Java code.

## 16.2. Die "from"-Klausel

Die einfachste Form der Hibernate-Anfrage lautet:

    from eg.Cat

This returns all instances of the class `eg.Cat`. You do not usually need to qualify the class name, since `auto-import` is the default. For example:

    from Cat

In order to refer to the `Cat` in other parts of the query, you will need to assign an alias. For example:

    from Cat as cat

This query assigns the alias `cat` to `Cat` instances, so you can use that alias later in the query. The `as` keyword is optional. You could also write:

    from Cat cat

Multiple classes can appear, resulting in a cartesian product or "cross" join.

    from Formula, Parameter

    from Formula as form, Parameter as param

It is good practice to name query aliases using an initial lowercase as this is consistent with Java naming standards for local variables (e.g. `domesticCat`).

## 16.3. Assoziationen und Verbünde ("Joins")

You can also assign aliases to associated entities or to elements of a collection of values using a `join`. For example:

    from Cat as cat
        inner join cat.mate as mate
        left outer join cat.kittens as kitten

    from Cat as cat left join cat.mate.kittens as kittens

    from Formula form full join form.parameter param

The supported join types are borrowed from ANSI SQL:

- `inner join`

- `left outer join`

- `right outer join`

- `full join` (in der Regel nicht sehr nützlich)

Die `inner join`, `left outer join` und `right outer join`-Konstrukte können abgekürzt werden.

    from Cat as cat
        join cat.mate as mate
        left join cat.kittens as kitten

Sie können weitere Verbundbedingungen unter Verwendung des HQL-Schlüsselbegriffs `with` eingeben.

    from Cat as cat
        left join cat.kittens as kitten
            with kitten.bodyWeight
    > 10.0

A "fetch" join allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections. See Abschnitt 21.1, „Abrufstrategien“ for more information.

    from Cat as cat
        inner join fetch cat.mate
        left join fetch cat.kittens

A fetch join does not usually need to assign an alias, because the associated objects should not be used in the `where` clause (or any other clause). The associated objects are also not returned directly in the query results. Instead, they may be accessed via the parent object. The only reason you might need an alias is if you are recursively join fetching a further collection:

    from Cat as cat
        inner join fetch cat.mate
        left join fetch cat.kittens child
        left join fetch child.kittens

The `fetch` construct cannot be used in queries called using `iterate()` (though `scroll()` can be used). `Fetch` should be used together with `setMaxResults()` or `setFirstResult()`, as these operations are based on the result rows which usually contain duplicates for eager collection fetching, hence, the number of rows is not what you would expect. `Fetch` should also not be used together with impromptu `with` condition. It is possible to create a cartesian product by join fetching more than one collection in a query, so take care in this case. Join fetching multiple collection roles can produce unexpected results for bag mappings, so user discretion is advised when formulating queries in this case. Finally, note that `full join fetch` and `right join fetch` are not meaningful.

If you are using property-level lazy fetching (with bytecode instrumentation), it is possible to force Hibernate to fetch the lazy properties in the first query immediately using `fetch all properties`.

    from Document fetch all properties order by name

    from Document doc fetch all properties where lower(doc.name) like '%cats%'

## 16.4. Formen der Verbundsyntax

HQL unterstützt zwei Arten von "Association-Joining": `implicit` und `explicit`.

The queries shown in the previous section all use the `explicit` form, that is, where the join keyword is explicitly used in the from clause. This is the recommended form.

Die `implicit`-Form verwendet den "Join"-Schlüsselbegriff nicht. Statt dessen sind die Assoziationen unter Verwendung von Punktnotation "dereferenziert". `implicit`-Joins können in jedem der HQL-Sätze erscheinen. `implicit`-Join-Ergebnisse resultieren in "inner Joins" in der sich ergebenden SQL-Anweisung.

    from Cat as cat where cat.mate.name like '%s%'

## 16.5. Referring to identifier property

There are 2 ways to refer to an entity's identifier property:

- The special property (lowercase) `id` may be used to reference the identifier property of an entity provided that the entity does not define a non-identifier property named id.

- If the entity defines a named identifier property, you can use that property name.

References to composite identifier properties follow the same naming rules. If the entity has a non-identifier property named id, the composite identifier property can only be referenced by its defined named. Otherwise, the special `id` property can be used to reference the identifier property.

## Wichtig

Please note that, starting in version 3.2.2, this has changed significantly. In previous versions, `id` always referred to the identifier property regardless of its actual name. A ramification of that decision was that non-identifier properties named `id` could never be referenced in Hibernate queries.

## 16.6. Die "select"-Klausel

The `select` clause picks which objects and properties to return in the query result set. Consider the following:

    select mate
    from Cat as cat
        inner join cat.mate as mate

The query will select `mate`s of other `Cat`s. You can express this query more compactly as:

    select cat.mate from Cat cat

Queries can return properties of any value type including properties of component type:

    select cat.name from DomesticCat cat
    where cat.name like 'fri%'

    select cust.name.firstName from Customer as cust

Queries can return multiple objects and/or properties as an array of type `Object[]`:

    select mother, offspr, mate.name
    from DomesticCat as mother
        inner join mother.mate as mate
        left outer join mother.kittens as offspr

Or as a `List`:

    select new list(mother, offspr, mate.name)
    from DomesticCat as mother
        inner join mother.mate as mate
        left outer join mother.kittens as offspr

Or - assuming that the class `Family` has an appropriate constructor - as an actual typesafe Java object:

    select new Family(mother, mate, offspr)
    from DomesticCat as mother
        join mother.mate as mate
        left join mother.kittens as offspr

You can assign aliases to selected expressions using `as`:

    select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
    from Cat cat

Das ist besonders in Verbindung mit `select new map` nützlich:

    select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
    from Cat cat

Diese Anfrage reagiert mit einer `Map` von Aliassen zu gewählten Werten.

## 16.7. Aggregierte Funktionen

HQL queries can even return the results of aggregate functions on properties:

    select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)
    from Cat cat

The supported aggregate functions are:

- `avg(...), sum(...), min(...), max(...)`

- `count(*)`

- `count(...), count(distinct ...), count(all...)`

You can use arithmetic operators, concatenation, and recognized SQL functions in the select clause:

    select cat.weight + sum(kitten.weight)
    from Cat cat
        join cat.kittens kitten
    group by cat.id, cat.weight

    select firstName||' '||initial||' '||upper(lastName) from Person

The `distinct` and `all` keywords can be used and have the same semantics as in SQL.

    select distinct cat.name from Cat cat

    select count(distinct cat.name), count(cat) from Cat cat

## 16.8. Polymorphe Anfragen

Eine Anfrage wie:

    from Cat as cat

returns instances not only of `Cat`, but also of subclasses like `DomesticCat`. Hibernate queries can name any Java class or interface in the `from` clause. The query will return instances of all persistent classes that extend that class or implement the interface. The following query would return all persistent objects:

    from java.lang.Object o

Das Interface `Named` könnte durch verschiedene persistente Klassen implementiert werden:

    from Named n, Named m where n.name = m.name

These last two queries will require more than one SQL `SELECT`. This means that the `order by` clause does not correctly order the whole result set. It also means you cannot call these queries using `Query.scroll()`.

## 16.9. Die "where"-Klausel

The `where` clause allows you to refine the list of instances returned. If no alias exists, you can refer to properties by name:

    from Cat where name='Fritz'

Falls ein Alias existiert, verwenden Sie einen vollständigen Property-Namen:

    from Cat as cat where cat.name='Fritz'

This returns instances of `Cat` named 'Fritz'.

The following query:

    select foo
    from Foo foo, Bar bar
    where foo.startDate = bar.date

returns all instances of `Foo` with an instance of `bar` with a `date` property equal to the `startDate` property of the `Foo`. Compound path expressions make the `where` clause extremely powerful. Consider the following:

    from Cat cat where cat.mate.name is not null

This query translates to an SQL query with a table (inner) join. For example:

    from Foo foo
    where foo.bar.baz.customer.address.city is not null

would result in a query that would require four table joins in SQL.

The `=` operator can be used to compare not only properties, but also instances:

    from Cat cat, Cat rival where cat.mate = rival.mate

    select cat, mate
    from Cat cat, Cat mate
    where cat.mate = mate

The special property (lowercase) `id` can be used to reference the unique identifier of an object. See Abschnitt 16.5, „Referring to identifier property“ for more information.

    from Cat as cat where cat.id = 123

    from Cat as cat where cat.mate.id = 69

The second query is efficient and does not require a table join.

Properties of composite identifiers can also be used. Consider the following example where `Person` has composite identifiers consisting of `country` and `medicareNumber`:

    from bank.Person person
    where person.id.country = 'AU'
        and person.id.medicareNumber = 123456

    from bank.Account account
    where account.owner.id.country = 'AU'
        and account.owner.id.medicareNumber = 123456

Once again, the second query does not require a table join.

See Abschnitt 16.5, „Referring to identifier property“ for more information regarding referencing identifier properties)

The special property `class` accesses the discriminator value of an instance in the case of polymorphic persistence. A Java class name embedded in the where clause will be translated to its discriminator value.

    from Cat cat where cat.class = DomesticCat

You can also use components or composite user types, or properties of said component types. See Abschnitt 16.17, „Komponenten“ for more information.

An "any" type has the special properties `id` and `class` that allows you to express a join in the following way (where `AuditLog.item` is a property mapped with `<any>`):

    from AuditLog log, Payment payment
    where log.item.class = 'Payment' and log.item.id = payment.id

The `log.item.class` and `payment.class` would refer to the values of completely different database columns in the above query.

## 16.10. Ausdrücke

Expressions used in the `where` clause include the following:

- mathematical operators: `+, -, *, /`

- binary comparison operators: `=, >=, <=, <>, !=, like`

- logische Vorgänge `and, or, not`

- Parentheses `( )` that indicates grouping

- `in`, `not in`, `between`, `is null`, `is not null`, `is empty`, `is not empty`, `member of` and `not member of`

- "Einfacher" Fall `case ... when ... then ... else ... end`, und "gesuchter" Fall `case when ... then ... else ... end`

- String-Verkettung `...||...` oder `concat(...,...)`

- `current_date()`, `current_time()`, and `current_timestamp()`

- `second(...)`, `minute(...)`, `hour(...)`, `day(...)`, `month(...)`, and `year(...)`

- Jede Funktion oder Operator definiert durch EJB-QL 3.0: `substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()`

- `coalesce()` und `nullif()`

- `str()` zur Konvertierung numerischer oder temporärer Werte in einen lesbaren String

- `cast(... as ...)`, wo ein zweites Argument der Name eines Hibernate-Typs ist und `extract(... from ...)`, wenn ANSI `cast()` und `extract()` von der zu Grunde liegenden Datenbank unterstützt werden

- die HQL `index()`-Funktion, die für Aliasse eine verbundenen indizierten Collection gilt

- HQL functions that take collection-valued path expressions: `size(), minelement(), maxelement(), minindex(), maxindex()`, along with the special `elements()` and `indices` functions that can be quantified using `some, all, exists, any, in`.

- Any database-supported SQL scalar function like `sign()`, `trunc()`, `rtrim()`, and `sin()`

- Positionelle Parameter im JDBC-Stil `?`

- named parameters `:name`, `:start_date`, and `:x1`

- SQL-Literale `'foo'`, `69`, `6.66E+2`, `'1970-01-01 10:00:01.0'`

- Java `public static final`-Konstanten `eg.Color.TABBY`

`in` and `between` can be used as follows:

    from DomesticCat cat where cat.name between 'A' and 'B'

    from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )

The negated forms can be written as follows:

    from DomesticCat cat where cat.name not between 'A' and 'B'

    from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )

Similarly, `is null` and `is not null` can be used to test for null values.

Booleans can be easily used in expressions by declaring HQL query substitutions in Hibernate configuration:

    <property name="hibernate.query.substitutions"
    >true 1, false 0</property
    >

Das ersetzt die Schlüsselbegriffe `true` und `false` durch die Literale `1` und `0` in der aus dieser HQL übersetzten SQL:

    from Cat cat where cat.alive = true

You can test the size of a collection with the special property `size` or the special `size()` function.

    from Cat cat where cat.kittens.size
    > 0

    from Cat cat where size(cat.kittens)
    > 0

For indexed collections, you can refer to the minimum and maximum indices using `minindex` and `maxindex` functions. Similarly, you can refer to the minimum and maximum elements of a collection of basic type using the `minelement` and `maxelement` functions. For example:

    from Calendar cal where maxelement(cal.holidays)
    > current_date

    from Order order where maxindex(order.items)
    > 100

    from Order order where minelement(order.items)
    > 10000

The SQL functions `any, some, all, exists, in` are supported when passed the element or index set of a collection (`elements` and `indices` functions) or the result of a subquery (see below):

    select mother from Cat as mother, Cat as kit
    where kit in elements(foo.kittens)

    select p from NameList list, Person p
    where p.name = some elements(list.names)

    from Cat cat where exists elements(cat.kittens)

    from Player p where 3
    > all elements(p.scores)

    from Show show where 'fizard' in indices(show.acts)

Note that these constructs - `size`, `elements`, `indices`, `minindex`, `maxindex`, `minelement`, `maxelement` - can only be used in the where clause in Hibernate3.

Elements of indexed collections (arrays, lists, and maps) can be referred to by index in a where clause only:

    from Order order where order.items[0].id = 1234

    select person from Person person, Calendar calendar
    where calendar.holidays['national day'] = person.birthDay
        and person.nationality.calendar = calendar

    select item from Item item, Order order
    where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11

    select item from Item item, Order order
    where order.items[ maxindex(order.items) ] = item and order.id = 11

The expression inside `[]` can even be an arithmetic expression:

    select item from Item item, Order order
    where order.items[ size(order.items) - 1 ] = item

HQL also provides the built-in `index()` function for elements of a one-to-many association or collection of values.

    select item, index(item) from Order order
        join order.items item
    where index(item) < 5

Scalar SQL functions supported by the underlying database can be used:

    from DomesticCat cat where upper(cat.name) like 'FRI%'

Consider how much longer and less readable the following query would be in SQL:

    select cust
    from Product prod,
        Store store
        inner join store.customers cust
    where prod.name = 'widget'
        and store.location.name in ( 'Melbourne', 'Sydney' )
        and prod = all elements(cust.currentOrder.lineItems)

Tipp: etwas wie

    SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order
    FROM customers cust,
        stores store,
        locations loc,
        store_customers sc,
        product prod
    WHERE prod.name = 'widget'
        AND store.loc_id = loc.id
        AND loc.name IN ( 'Melbourne', 'Sydney' )
        AND sc.store_id = store.id
        AND sc.cust_id = cust.id
        AND prod.id = ALL(
            SELECT item.prod_id
            FROM line_items item, orders o
            WHERE item.order_id = o.id
                AND cust.current_order = o.id
        )

## 16.11. Die Reihenfolge nach Klausel

The list returned by a query can be ordered by any property of a returned class or components:

    from DomesticCat cat
    order by cat.name asc, cat.weight desc, cat.birthdate

Die optionalen `asc` oder `desc` zeigen die aufsteigende bzw. absteigende Reihenfolge an.

## 16.12. Die Gruppe nach Klausel

A query that returns aggregate values can be grouped by any property of a returned class or components:

    select cat.color, sum(cat.weight), count(cat)
    from Cat cat
    group by cat.color

    select foo.id, avg(name), max(name)
    from Foo foo join foo.names name
    group by foo.id

Eine `having`-Klausel ist ebenfalls gestattet.

    select cat.color, sum(cat.weight), count(cat)
    from Cat cat
    group by cat.color
    having cat.color in (eg.Color.TABBY, eg.Color.BLACK)

SQL functions and aggregate functions are allowed in the `having` and `order by` clauses if they are supported by the underlying database (i.e., not in MySQL).

    select cat
    from Cat cat
        join cat.kittens kitten
    group by cat.id, cat.name, cat.other, cat.properties
    having avg(kitten.weight)
    > 100
    order by count(kitten) asc, sum(kitten.weight) desc

Neither the `group by` clause nor the `order by` clause can contain arithmetic expressions. Hibernate also does not currently expand a grouped entity, so you cannot write `group by cat` if all properties of `cat` are non-aggregated. You have to list all non-aggregated properties explicitly.

## 16.13. Unteranfragen

Für Datenbanken, die Unterauswahlen unterstützen, unterstützt Hibernate innerhalb von Anfragen Unteranfragen. Eine Unteranfrage muss eingeklammert sein (oftmals durch einen SQL aggregierten Funktionsaufruf). Selbst korrelierende Unteranfragen (Unteranfragen, die auf einen Alias in der außerhalb liegenden Anfrage verweisen) sind gestattet.

    from Cat as fatcat
    where fatcat.weight
    > (
        select avg(cat.weight) from DomesticCat cat
    )

    from DomesticCat as cat
    where cat.name = some (
        select name.nickName from Name as name
    )

    from Cat as cat
    where not exists (
        from Cat as mate where mate.mate = cat
    )

    from DomesticCat as cat
    where cat.name not in (
        select name.nickName from Name as name
    )

    select cat.id, (select max(kit.weight) from cat.kitten kit)
    from Cat as cat

Note that HQL subqueries can occur only in the select or where clauses.

Note that subqueries can also utilize `row value constructor` syntax. See Abschnitt 16.18, „Die Syntax des "Row-Value-Constructors"“ for more information.

## 16.14. HQL-Beispiele

Hibernate queries can be quite powerful and complex. In fact, the power of the query language is one of Hibernate's main strengths. The following example queries are similar to queries that have been used on recent projects. Please note that most queries you will write will be much simpler than the following examples.

The following query returns the order id, number of items, the given minimum total value and the total value of the order for all unpaid orders for a particular customer. The results are ordered by total value. In determining the prices, it uses the current catalog. The resulting SQL query, against the `ORDER`, `ORDER_LINE`, `PRODUCT`, `CATALOG` and `PRICE` tables has four inner joins and an (uncorrelated) subselect.

    select order.id, sum(price.amount), count(item)
    from Order as order
        join order.lineItems as item
        join item.product as product,
        Catalog as catalog
        join catalog.prices as price
    where order.paid = false
        and order.customer = :customer
        and price.product = product
        and catalog.effectiveDate < sysdate
        and catalog.effectiveDate
    >= all (
            select cat.effectiveDate
            from Catalog as cat
            where cat.effectiveDate < sysdate
        )
    group by order
    having sum(price.amount)
    > :minAmount
    order by sum(price.amount) desc

Monströs! Im wirklichen Leben bin ich kein großer Freund von Unteranfragen, daher sieht meine Anfrage eher wie folgt aus:

    select order.id, sum(price.amount), count(item)
    from Order as order
        join order.lineItems as item
        join item.product as product,
        Catalog as catalog
        join catalog.prices as price
    where order.paid = false
        and order.customer = :customer
        and price.product = product
        and catalog = :currentCatalog
    group by order
    having sum(price.amount)
    > :minAmount
    order by sum(price.amount) desc

Die nächste Anfrage zählt die Anzahl von Zahlungen in jedem Status, wobei Zahlungen mit `AWAITING_APPROVAL`-Status, bei denen die aktuellste Statusänderung durch den Benutzer vorgenommen wurde, ausgenommen sind. Sie wird in eine SQL-Anfrage mit zwei inneren Verbünden und eine korrelierte Unterauswahl an die `PAYMENT`, `PAYMENT_STATUS` und `PAYMENT_STATUS_CHANGE`-Tabellen übersetzt.

    select count(payment), status.name
    from Payment as payment
        join payment.currentStatus as status
        join payment.statusChanges as statusChange
    where payment.status.name <
    > PaymentStatus.AWAITING_APPROVAL
        or (
            statusChange.timeStamp = (
                select max(change.timeStamp)
                from PaymentStatusChange change
                where change.payment = payment
            )
            and statusChange.user <
    > :currentUser
        )
    group by status.name, status.sortOrder
    order by status.sortOrder

If the `statusChanges` collection was mapped as a list, instead of a set, the query would have been much simpler to write.

    select count(payment), status.name
    from Payment as payment
        join payment.currentStatus as status
    where payment.status.name <
    > PaymentStatus.AWAITING_APPROVAL
        or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <
    > :currentUser
    group by status.name, status.sortOrder
    order by status.sortOrder

Die nächste Anfrage verwendet die MS SQL Server `isNull()`-Funktion, um alle Konten und unbezahlten Zahlungen für the Organisation, zu der der aktuelle Benutzer gehört, wiederzugeben. Sie wird in eine SQL-Anfrage mit drei inneren Verbünden ("inner Joins"), einen äußeren Verbund ("outer Join") und eine Unterauswahl gegen die `ACCOUNT`, `PAYMENT`, `PAYMENT_STATUS`, `ACCOUNT_TYPE`, `ORGANIZATION` und `ORG_USER`-Tabellen übersetzt.

    select account, payment
    from Account as account
        left outer join account.payments as payment
    where :currentUser in elements(account.holder.users)
        and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
    order by account.type.sortOrder, account.accountNumber, payment.dueDate

Bei einigen Datenbanken würden wir die (korrelierende) Unterauswahl abschaffen müssen.

    select account, payment
    from Account as account
        join account.holder.users as user
        left outer join account.payments as payment
    where :currentUser = user
        and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID)
    order by account.type.sortOrder, account.accountNumber, payment.dueDate

## 16.15. "Bulk"-Aktualisierung und Löschen

HQL now supports `update`, `delete` and `insert ... select ...` statements. See Abschnitt 15.4, „Vorgänge im DML-Stil“ for more information.

## 16.16. Tipps & Tricks

You can count the number of query results without returning them:

    ( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()

Um ein Ergebnis nach der Größe einer Collection zu ordnen, verwenden Sie die folgende Anfrage:

    select usr.id, usr.name
    from User as usr
        left join usr.messages as msg
    group by usr.id, usr.name
    order by count(msg)

Falls Ihre Datenbank Unterauswahlen unterstützt, können Sie eine Bedingung bezüglich der Auswahlgröße in der "where"-Klausel Ihrer Anfrage stellen:

    from User usr where size(usr.messages)
    >= 1

If your database does not support subselects, use the following query:

    select usr.id, usr.name
    from User usr
        join usr.messages msg
    group by usr.id, usr.name
    having count(msg)
    >= 1

As this solution cannot return a `User` with zero messages because of the inner join, the following form is also useful:

    select usr.id, usr.name
    from User as usr
        left join usr.messages as msg
    group by usr.id, usr.name
    having count(msg) = 0

Properties eines JavaBean können an benannte Anfragenparameter gebunden werden:

    Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");

    q.setProperties(fooBean); // fooBean has getName() and getSize()

    List foos = q.list();

Collections sind unter Verwendung des `Query`-Interface mit einem Filter seitenwechselbar:

    Query q = s.createFilter( collection, "" ); // the trivial filter

    q.setMaxResults(PAGE_SIZE);

    q.setFirstResult(PAGE_SIZE * pageNumber);

    List page = q.list();

Collection elements can be ordered or grouped using a query filter:

    Collection orderedCollection = s.filter( collection, "order by this.amount" );

    Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );

Sie können die Größe einer Collection finden, ohne diese zu initialisieren:

    ( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();

## 16.17. Komponenten

Components can be used similarly to the simple value types that are used in HQL queries. They can appear in the `select` clause as follows:

    select p.name from Person p

    select p.name.first from Person p

wo die Namen-Property der Person eine Komponente ist. Komponenten können auch in der `where`-Klausel verwendet werden:

    from Person p where p.name = :name

    from Person p where p.name.first = :firstName

Komponenten können auch in der `order by`-Klausel verwendet werden:

    from Person p order by p.name

    from Person p order by p.name.first

Another common use of components is in row value constructors.

## 16.18. Die Syntax des "Row-Value-Constructors"

HQL supports the use of ANSI SQL `row value constructor` syntax, sometimes referred to AS `tuple` syntax, even though the underlying database may not support that notion. Here, we are generally referring to multi-valued comparisons, typically associated with components. Consider an entity Person which defines a name component:

    from Person p where p.name.first='John' and p.name.last='Jingleheimer-Schmidt'

That is valid syntax although it is a little verbose. You can make this more concise by using `row value constructor` syntax:

    from Person p where p.name=('John', 'Jingleheimer-Schmidt')

Es kann sich als nützlich erweisen, dies in der `select`-Klausel zu spezifizieren:

    select p.name from Person p

Using `row value constructor` syntax can also be beneficial when using subqueries that need to compare against multiple values:

    from Cat as cat
    where not ( cat.name, cat.color ) in (
        select cat.name, cat.color from DomesticCat cat
    )

One thing to consider when deciding if you want to use this syntax, is that the query will be dependent upon the ordering of the component sub-properties in the metadata.

Copyright © 2004 Red Hat, Inc.

- ZurückKapitel 15. Batch-Verarbeitung
- Nach oben
- Zum Anfang
- WeiterKapitel 17. "Criteria Queries"