Hibernate.orgCommunity Documentation
Hibernate は SQL に非常によく似た (意図的に似せた) 強力な問い合わせ言語を備えています。しかし SQL に似た構文に惑わされないでください。 HQL は完全にオブジェクト指向であり、継承、ポリモーフィズム、関連といった概念を理解します。
クエリは Java のクラス名とプロパティ名を除いて大文字、小文字を区別しません。従って SeLeCT
は sELEct
と同じで、かつ SELECT
とも同じですが org.hibernate.eg.FOO
は org.hibernate.eg.Foo
とは違い、かつ foo.barSet
は foo.BARSET
とも違います。
このマニュアルでは小文字の HQL キーワードを使用します。大文字のキーワードのクエリの方が読みやすいと感じるユーザーもいると思います。ですが、 Java コード内に埋め込まれたときには見づらいと思います。
もっとも単純な Hibernate クエリは次の形式です:
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
このクエリでは Cat
インスタンスに cat
という別名を付けています。そのため、後でこのクエリ内で、この別名を使うことができます。 as
キーワードはオプションです。つまりこのように書くこともできます:
from Cat cat
直積、あるいは「クロス」結合によって多数のクラスが出現することもあります。
from Formula, Parameter
from Formula as form, Parameter as param
ローカル変数の Java のネーミング基準と一致した、頭文字に小文字を使ったクエリの別名を付けることはいい習慣です (例えば domesticCat
)。
関連するエンティティあるいは値コレクションの要素にも、 結合
を使って別名を割り当てることが出来ます。
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
サポートしている結合のタイプは ANSI SQL と同じです。
inner join
left outer join
right outer join
full join
(たいていの場合使いづらい)
inner join
、 left outer join
、 right outer join
には省略形を使うこともできます。
from Cat as cat join cat.mate as mate left join cat.kittens as kitten
HQL の with
キーワードを使うと、結合条件を付け加えることができます。
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 「フェッチ戦略」 for more information.
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens
結合によるフェッチは関連するオブジェクトが where
節 (または他のどんな節でも) で使われてはならないので、通常別名を割り当てる必要がありません。また関連オブジェクトは問い合わせ結果として直接返されません。代わりに親オブジェクトを通してアクセスできます。コレクションを再帰的に結合フェッチする場合のみ、別名が必要になります:
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens child left join fetch child.kittens
fetch
構文は iterate()
を使ったクエリ呼び出しで使用できないことに注意してください (一方で scroll()
は使用できます)。また、これらの操作は結果の行に基づいているため、 fetch
は setMaxResults()
や setFirstResult()
と一緒に使用すべきではありません。通常 eager なコレクションフェッチをすると重複が出てしまうため、あなたが期待するような行数にはならないのです。そしてまた fetch
は、アドホックな with
条件を一緒に使うこともできません。一つのクエリで複数のコレクションを結合フェッチすることにより直積を作成できるので、この場合注意してください。また、複数のコレクションに対する結合フェッチは bag マッピングに対して予期せぬ結果をもたらすことがあるので、この場合のクエリの作成には注意してください。最後に 全外部結合によるフェッチ
と 右外部結合によるフェッチ
は有用ではないことに注意してください。
もしプロパティレベルの遅延フェッチを使う場合(内部的にバイトコード処理をする場合)、 fetch all properties
を使うことで Hibernate に遅延プロパティを速やかに(最初のクエリで)フェッチさせることができます。
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like '%cats%'
HQL は2つの関連結合形式をサポートします: 暗黙的
と 明示的
。
これまでのセクションでお見せした使い方はすべて 明示的な
形式で、 from 節で明示的に join キーワードを使っています。この形式をおすすめします。
暗黙的
フォームは、 join キーワードを使いません。代わりに、参照する関連にドット表記を使います。 暗黙的
結合は、さまざまな HQL に出てきます。 暗黙的
結合の結果は、 SQL ステートメントの内部結合結果です。
from Cat as cat where cat.mate.name like '%s%'
エンティティの識別子プロパティは、一般的に2つの方法で参照されます:
特別なプロパティ (小文字) id
は、 id と名付けられた非識別子プロパティを定義しないエンティティを与えられた エンティティの識別子プロパティを参照するのに使用されます。
もしエンティティが名付けられた識別子プロパティを定義したら、そのプロパティ名を使用できます。
複合識別子プロパティへの参照は同じ命名ルールに従います。もしエンティティが id と名付けられた非識別子プロパティを持っていたら、複合識別子プロパティはその定義された名前で参照することができます。そうでないと、特別な id
プロパティは、識別子プロパティを参照するのに使用されます。
注記: これは、バージョン 3.2.2 から大幅に変更しました。前バージョンでは、 id
は、その実際の名前に関係なく 常に 識別子プロパティを参照していました。その結果、 id
と名付けられた非識別子プロパティは、 Hibernate で決して参照されませんでした。
select
節は以下のようにどのオブジェクトと属性をクエリリザルトセットに返すかを選択します:
select mate from Cat as cat inner join cat.mate as mate
上記のクエリは他の Cat
の mate
を選択します。実際には次のように、より簡潔に表現できます:
select cat.mate from Cat cat
クエリはコンポーネント型のプロパティを含む、あらゆる値型のプロパティも返せます:
select cat.name from DomesticCat cat where cat.name like 'fri%'
select cust.name.firstName from Customer as cust
クエリは複数のオブジェクトと (または) プロパティを Object[]
型の配列として返せます。
select mother, offspr, mate.name from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
もしくは 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
あるいは Family
クラスが適切なコンストラクタを持っているとするならば、
select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr
select 節に as
を使って別名をつけることもできます。
select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n from Cat cat
select new map
と一緒に使うときに最も役立ちます:
select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n ) from Cat cat
このクエリは別名から select した値へ Map
を返します。
HQL のクエリはプロパティの集約関数の結果も返せます:
select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from Cat cat
サポートしている集約関数は以下のものです。
avg(...), sum(...), min(...), max(...)
count(*)
count(...), count(distinct ...), count(all...)
select 節において算術操作、連結と承認された SQL 関数を使うことができます:
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
SQL と同じ意味を持つ distinct
と all
キーワードを使うことができます。
select distinct cat.name from Cat cat select count(distinct cat.name), count(cat) from Cat cat
次のようなクエリ:
from Cat as cat
Cat
インスタンスだけではなく、 DomesticCat
のようなサブクラスも返されます。 Hibernate クエリは どんな Java クラスやインターフェースも from
節に入れることができます。クエリはそのクラスを拡張した、もしくはインターフェースを実装した全ての永続クラスを返します。次のクエリは永続オブジェクトをすべて返します:
from java.lang.Object o
Named
インターフェースは様々な永続クラスによって実装されます。:
from Named n, Named m where n.name = m.name
最後の2つのクエリは、2つ以上の SQL SELECT
を要求していることに注意してください。このことは order by
節がリザルトセット全体を正確には整列しないことを意味します (さらにそれは、 Query.scroll()
を使用してこれらのクエリを呼ぶことができないことを意味します。)。
where
節は返されるインスタンスのリストを絞ることができます。もし別名がない場合、名前でプロパティを参照します。
from Cat where name='Fritz'
もし別名がある場合、修飾名を使ってください:
from Cat as cat where cat.name='Fritz'
名前が 'Fritz' という Cat
のインスタンスを返します。
The following query:
select foo from Foo foo, Bar bar where foo.startDate = bar.date
上の HQL は、 Foo
の startDate
プロパティと等しい date
プロパティを持った bar
インスタンスが存在する、すべての Foo
インスタンスを返します。コンパウンドパス式は where
節を非常に強力にします。注目:
from Cat cat where cat.mate.name is not null
このクエリはテーブル結合(内部結合)を持つ SQL クエリに変換されます。その代わりに以下のように書くと、
from Foo foo where foo.bar.baz.customer.address.city is not null
もし上のクエリを記述したらクエリ内に4つのテーブル結合を必要とする SQL クエリに変換されます。
=
演算子は以下のように、プロパティだけでなくインスタンスを比較するためにも使われます。:
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 「識別子プロパティの参照」 for more information.
from Cat as cat where cat.id = 123 from Cat as cat where cat.mate.id = 69
2番目のクエリは効率的です。テーブル結合が必要ありません。
また複合識別子のプロパティも使用できます。ここで Person
が country
と 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
繰り返しますが、2番目のクエリにはテーブル結合が必要ありません。
See 「識別子プロパティの参照」 for more information regarding referencing identifier properties)
同様に class
は特別なプロパティであり、ポリモーフィックな永続化におけるインスタンスの discriminator 値にアクセスします。 where 節に埋め込まれた Java のクラス名はその discriminator 値に変換されます。
from Cat cat where cat.class = DomesticCat
You can also use components or composite user types, or properties of said component types. See 「コンポーネント」 for more information.
"any" 型は特別なプロパティである id
と class
を持ち、以下の方法で結合を表現することを可能にします (AuditLog.item
は <any>
でマッピングされたプロパティです)。
from AuditLog log, Payment payment where log.item.class = 'Payment' and log.item.id = payment.id
log.item.class
と payment.class
が上記のクエリ中で全く異なるデータベースカラムの値を参照するということに注意してください。
Expressions used in the where
clause include the following:
算術演算子:+, -, *, /
2項比較演算子:=, >=, <=, <>, !=, like
論理演算子:and, or, not
グループ分けを表す括弧:( )
in
, not in
, between
, is null
, is not null
, is empty
, is not empty
, member of
and not member of
"シンプル"な case case ... when ... then ... else ... end
、 "探索的"な case case when ... then ... else ... end
ストリングの連結 ...||...
または concat(...,...)
current_date()
, current_time()
, current_timestamp()
second(...)
, minute(...)
, hour(...)
, day(...)
, month(...)
, year(...)
,
EJB-QL 3.0 で定義されている関数や演算子: substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()
coalesce()
と nullif()
数字や時間の値を String にコンバートする str()
2番目の引数が Hibernate 型の名前である cast(... as ...)
と extract(... from ...)
。ただし使用するデータベースが ANSI cast()
と extract()
をサポートする場合に限ります。
結合したインデックス付きのコレクションの別名に適用される HQL の index()
関数。
コレクション値のパス式を取る HQL 関数: size(), minelement(), maxelement(), minindex(), maxindex()
。 some, all, exists, any, in
を使って修飾することができる特別な elements()
と indices
関数と一緒に使います。
sign()
、 trunc()
、 rtrim()
、 sin()
のようなデータベースがサポートする SQL スカラ関数。
JDBC スタイルの位置パラメータ ?
名前付きパラメータ: :name
, :start_date
, :x1
SQL リテラル: 'foo'
、 69
、 6.66E+2
、 '1970-01-01 10:00:01.0'
Java の public static final
定数: eg.Color.TABBY
in
と between
は以下のように使用できます:
from DomesticCat cat where cat.name between 'A' and 'B'
from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
また、否定形で記述することもできます。
from DomesticCat cat where cat.name not between 'A' and 'B'
from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
同様に is null
や is not null
は null 値をテストするために使用できます。
Hibernate 設定ファイルで HQL query substitutions を定義すれば、 boolean 値を式の中で簡単に使用できます:
<property name="hibernate.query.substitutions" >true 1, false 0</property >
こうすることで下記の HQL を SQL に変換するときに true
、 false
キーワードは 1
、 0
に置き換えられます:
from Cat cat where cat.alive = true
特別なプロパティ size
、または特別な関数 size()
を使ってコレクションのサイズをテストできます:
from Cat cat where cat.kittens.size > 0
from Cat cat where size(cat.kittens) > 0
インデックス付きのコレクションでは、 minindex
と maxindex
関数を使って、インデックスの最小値と最大値を参照できます。同様に、 minelement
と maxelement
を使って、基本型のコレクション要素の最小値と最大値を参照できます。
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
コレクションの要素やインデックスのセット(elements
と indices
関数)、または副問い合わせ(後述)の結果が受け取れるときは、 SQL 関数 any, some, all, exists, in
がサポートされます。
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)
size
、 elements
、 indices
、 minindex
、 maxindex
、 minelement
、 maxelement
は Hibernate3 の where 節だけで利用可能であることに注意してください。
インデックス付きのコレクション(arrays, lists, maps)の要素は、インデックスで参照できます(where節内でのみ):
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
[]
内部の式は、算術式でも構いません。
select item from Item item, Order order where order.items[ size(order.items) - 1 ] = item
一対多関連や値のコレクションの要素に対しては、 HQL は組み込みの index()
関数も用意しています。
select item, index(item) from Order order join order.items item where index(item) < 5
ベースとなるデータベースがサポートしているスカラー SQL 関数が使用できます:
from DomesticCat cat where upper(cat.name) like 'FRI%'
もしまだ全てを理解していないなら、下のクエリを 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)
ヒント: 例えばこのように出来ます。
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 )
クエリが返す list は、返されるクラスやコンポーネントの任意の属性によって並べ替えられます:
from DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate
オプションの asc
と desc
はそれぞれ昇順か降順の整列を示します。
集約値を返すクエリは、返されるクラスやコンポーネントの任意のプロパティによってグループ化できます:
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
having
節も使えます。
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)
もし使用するデータベースがサポートしているなら、 having
と order by
節で SQL 関数と集約関数が使えます(例えば 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
group by
節や order by
節に算術式を含むことができないことに注意してください。また、 Hibernate は今のところグループエンティティを拡張しないことにも注意してください。したがって、もし cat
の全てのプロパティが非集合体の場合、 group by cat
を書くことはできません。全ての非集合体のプロパティを明示的にリストする必要があります。
サブセレクトをサポートするデータベースのため、 Hibernate は副問い合わせをサポートしています。副問い合わせは括弧で囲まなければなりません( SQL の集約関数呼び出しによる事が多いです)。関連副問い合わせ (外部クエリ中の別名を参照する副問い合わせのこと) さえ許可されます。
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
HQL 副問い合わせは、 select または where 節だけで使われることに注意してください。
Note that subqueries can also utilize row value constructor
syntax. See 「行値コンストラクタ構文」 for more information.
Hibernate クエリは非常に強力で複雑にできます。実際、クエリ言語の威力は Hibernate の主要なセールスポイントの一つです。ここに最近のプロジェクトで使用したクエリと非常によく似た例があります。ほとんどのクエリはこれらの例より簡単に記述できることに注意してください。
以下のクエリは特定の顧客と与えられた最小の合計値に対する未払い注文の注文 ID 、商品の数、注文の合計を合計値で整列して返します。価格を決定する際、現在のカタログを使います。結果として返される SQL クエリは ORDER
、 ORDER_LINE
、 PRODUCT
、 CATALOG
および PRICE
テーブルに対し4つの内部結合と (関連しない) 副問い合わせを持ちます。
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
何て巨大なクエリなのでしょう。普段私は副問い合わせをあまり使いません。したがって私のクエリは実際には以下のようになります。:
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
次のクエリは各ステータスの支払い数を数えます。ただしすべての支払いが現在の利用者による最新のステータス変更である AWAITING_APPROVAL
である場合を除きます。このクエリは2つの内部結合と PAYMENT
, PAYMENT_STATUS
および PAYMENT_STATUS_CHANGE
テーブルに対する関連副問い合わせを備えた SQL クエリに変換されます。
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
もし set の代わりに list として statusChanges
コレクションをマッピングしたならば、はるかに簡単にクエリを記述できるでしょう。
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
次のクエリは現在のユーザーが所属する組織に対するアカウントおよび未払いの支払いをすべて返す MS SQL Server の isNull()
関数を使用しています。このクエリは3つの内部結合と1つの外部結合、そして ACCOUNT
、 PAYMENT
、 PAYMENT_STATUS
、 ACCOUNT_TYPE
、 ORGANIZATION
および ORG_USER
テーブルに対する副問い合わせ持った SQL に変換されます。
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
いくつかのデータベースについては、 (関連させられた) 副問い合わせの使用を避ける必要があるでしょう。
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
HQL now supports update
, delete
and insert ... select ...
statements. See 「DML スタイルの操作」 for more information.
実際に結果を返さなくてもクエリの結果数を数えることができます:
( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()
コレクションのサイズにより結果を並べ替えるためには以下のクエリを使用します:
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)
使用しているデータベースがサブセレクトをサポートする場合、クエリの where 節でサイズによる選択条件を設定できます:
from User usr where size(usr.messages) >= 1
使用しているデータベースがサブセレクトをサポートしない場合は、次のクエリを使用してください:
select usr.id, usr.name from User usr join usr.messages msg group by usr.id, usr.name having count(msg) >= 1
内部結合をしているせいで上の解決法が message の件数がゼロの User
を返すことができないならば、以下の形式が使えます:
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
JavaBean のプロパティは、名前付きのクエリパラメータに結びつけることが出来ます:
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();
コレクションはフィルタ付き Query
インターフェースを使用することでページをつけることができます:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
コレクションの要素はクエリフィルタを使って、並べ替えやグループ分けが出来ます:
Collection orderedCollection = s.filter( collection, "order by this.amount" );
Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );
コレクションを初期化せずにコレクションのサイズを得ることができます:
( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();
HQL クエリでシンプルな値型を使用できるので、コンポーネントは、あらゆる点で使用できます。これは select
節の中に現われます:
select p.name from Person p
select p.name.first from Person p
人名のプロパティがコンポーネントの場所。コンポーネントは、 where
節でも使用可能です:
from Person p where p.name = :name
from Person p where p.name.first = :firstName
コンポーネントは order by
節でも使用可能です:
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.
下に位置するデータベースが ANSI SQL row value constructor
構文 (tuple
構文とよばれることもあります) をサポートしていないとしても、 HQL はその使用をサポートしています。ここでは、一般的にコンポーネントと連繋するマルチバリュー比較について触れます。ネームコンポーネントを定義する Person エンティティを考えましょう:
from Person p where p.name.first='John' and p.name.last='Jingleheimer-Schmidt'
それは少々詳細になりますが、有効な構文です。より簡潔にし、 row value constructor
構文を使用するのがよいでしょう:
from Person p where p.name=('John', 'Jingleheimer-Schmidt')
それを select
節で指定するのも効果的です。
select p.name from Person p
次に row value constructor
構文の使用が有効なときは、サブクエリを使用して複数の値と比較する必要があるときです:
from Cat as cat where not ( cat.name, cat.color ) in ( select cat.name, cat.color from DomesticCat cat )
この構文を使用するかどうか決定するときに考慮しなければならないことは、クエリがメタデータ内のコンポーネントのサブプロパティの順番に依存していることです。
製作著作 © 2004 Red Hat, Inc.