HIBERNATE - Relational Persistence for Idiomatic Java
Hibernate Reference Documentation
Hibernateレファレンスドキュメンテーション
3.2.2
Table of Contents(コンテンツテーブル)
Preface(序文)
1. Introduction to Hibernate(Hibernateの紹介)
2. Architecture(アーキテクチャ)
3. Configuration(設定)
6. Collection Mapping(コレクションのマッピング)
7. Association Mappings(関連マッピング)
8. Component Mappingコンポーネントのマッピング
9. Inheritance Mapping(継承マッピング)
10. Working with objects(オブジェクトを扱う)
11. Transactions And Concurrency(トランザクションと並行性)
12. Interceptors and events(インターセプタとイベント)
13. Batch processing(バッチ処理)
14.2. The from clause(from節)
14.3. Associations and joins(関連と結合)
14.4. Forms of join syntax(結合構文の形式)
14.5. Refering to identifier property(識別子プロパティの参照)
14.6. The select clause(select節)
14.7. Aggregate functions(集約関数)
14.8. Polymorphic queries(ポリモーフィックなクエリ)
14.9. The where clause(where節)
14.10. Expressions(Expression式)
14.11. The order by clause(order by節)
14.12. The group by clause(group by節)
14.13. Subqueries(サブクエリ)
14.14. HQL examples(HQL例)
14.17. Components(コンポーネント)
14.18. Row value constructor syntax
Chapter 14. HQL: The Hibernate Query Language(第14章:HQL:Hibernateクエリ言語)
Hibernate is equipped with an extremely powerful query language that (quite intentionally) looks very much like SQL. But don't be fooled by the syntax; HQL is fully object-oriented, understanding notions like inheritence, polymorphism and association.
HibernateはSQLに非常によく似た(意図的に似せた)強力な問い合わせ言語を備えています。しかしSQLに似た構文に惑わされないでください。HQLは完全にオブジェクト指向であり、継承、ポリモーフィズム、関連といった概念を理解します。
14.1. Case Sensitivity(大文字と小文字の区別)
Queries are case-insensitive, except for names of Java classes and properties. So SeLeCTis the same as sELEct is the same as SELECT but org.hibernate.eg.FOO is notorg.hibernate.eg.Foo and foo.barSet is not foo.BARSET.
クエリはJavaのクラス名とプロパティ名を除いて大文字、小文字を区別しません。従ってSeLeCTはsELEctと同じで、かつSELECTとも同じですがnet.sf.hibernate.eg.FOOはnet.sf.hibernate.eg.Fooとは違い、かつfoo.barSetはfoo.BARSETとも違います。
This manual uses lowercase HQL keywords. Some users find queries with uppercase keywords more readable, but we find this convention ugly when embedded in Java code.
このマニュアルでは小文字のHQLキーワードを使用します。大文字のキーワードのクエリの方が読みやすいと感じるユーザーもいると思います。ですが、Javaコード内に埋め込まれたときには見づらいと思います。
14.2. The from clause(from節)
The simplest possible Hibernate query is of the form:
もっと単純なHibernateクエリは次の形式です。
from eg.Cat
which simply returns all instances of the class eg.Cat. We don't usually need to qualify the class name, since auto-import is the default. So we almost always just write:
これは単純にeg.Catクラスのインスタンスをすべて返します。必ずしもクラス名を修飾する(クラスにパッケージ名を付ける)必要はありません。というのも、auto-importがデフォルトになっているからです。そのためほとんどの場合、このように書くだけで十分です。
from Cat
Most of the time, you will need to assign an alias, since you will want to refer to the Catin other parts of the query.
ほとんどの場合クエリのほかの部分で Cat を参照するので、別名を割り当てる必要があるでしょう。
from Cat as cat
This query assigns the alias cat to Cat instances, so we could use that alias later in the query. The as keyword is optional; we could also write:
このクエリではCatインスタンスにcatという別名を付けています。そのため、後でこのクエリ内で、この別名を使うことができます。asキーワードはオプションです。つまりこのように書くこともできます:
from Cat cat
Multiple classes may appear, resulting in a cartesian product or "cross" join.
直積、あるいはクロス結合によって多数のクラスが出現することもあります。
from Formula, Parameter
from Formula as form, Parameter as param
It is considered good practice to name query aliases using an initial lowercase, consistent with Java naming standards for local variables (eg. domesticCat).
ローカル変数のJavaのネーミング基準と一致した、頭文字に小文字を使ったクエリの別名を付けることはいい習慣です(例えばdomesticCat)。
14.3. Associations and joins(関連と結合)
We may also assign aliases to associated entities, or even to elements of a collection of values, using a join.
関連するエンティティあるいは値コレクションの要素にも、結合を使って別名を割り当てることが出来ます。
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
サポートしている結合のタイプはANSI SQLと同じです。
? inner join
? left outer join
? right outer join
? full join (not usually useful)
The inner join, left outer join and right outer join constructs may be abbreviated.
inner join、left outer join、right outer joinには省略形を使うこともできます。
from Cat as cat
join cat.mate as mate
left join cat.kittens as kitten
You may supply extra join conditions using the HQL with keyword.
HQLのwithキーワードを使うと、結合条件を付け加えることができます。
from Cat as cat
left join cat.kittens as kitten
with kitten.bodyWeight > 10.0
In addition, 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 Section 19.1, "Fetching strategies" for more information.
加えて、「フェッチ」結合は関連や値のコレクションを親オブジェクトと一緒に1度のselect句で初期化します。これは特にコレクションの場合に有用です。これは実質上、関連とコレクションに対するマッピング定義ファイルの外部結合とlazy初期化の定義を上書きすることになります。Section 19.1, "Fetching strategies"により多くの情報があります。
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). Also, the associated objects are not returned directly in the query results. Instead, they may be accessed via the parent object. The only reason we might need an alias is if we are recursively join fetching a further collection:
結合によるフェッチは関連するオブジェクトがwhere節(または他のどんな節でも)で使われてはならないので、通常別名を割り当てる必要がありません。また関連オブジェクトは問い合わせ結果として直接返されません。代わりに親オブジェクトを通してアクセスできます。コレクションを再帰的に結合フェッチする場合のみ、別名が必要になります。
from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens child
left join fetch child.kittens
Note that the fetch construct may not be used in queries called using iterate() (thoughscroll() can be used). Nor should fetch be used together with setMaxResults() orsetFirstResult() 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'd expect. Nor may fetch be used together with an ad hoc 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 also sometimes gives unexpected results for bag mappings, so be careful about how you formulate your queries in this case. Finally, note that full join fetch and right join fetch are not meaningful.
fetch構文はiterate()を使ったクエリ呼び出しで使用できないことに注意してください(一方でscroll()は使用できます)。また、これらの操作は結果の行に基づいているため、fetchはsetMaxResults()やsetFirstResult()と一緒に使用すべきではありません。通常eagerなコレクションフェッチをすると重複が出てしまうため、あなたが期待するような行数にはならないのです。そしてまたfetchは、アドホックなwith条件を一緒に使うこともできません。一つのクエリで複数のコレクションを結合フェッチすることにより直積を作成できるので、この場合注意してください。また、複数のコレクションに対する結合フェッチはbagマッピングに対して予期せぬ結果をもたらすことがあるので、この場合のクエリの作成には注意してください。最後に全外部結合によるフェッチと右外部結合によるフェッチは有用ではないことに注意してください。
If you are using property-level lazy fetching (with bytecode instrumentation), it is possible to force Hibernate to fetch the lazy properties immediately (in the first query) using fetch all properties.
もしプロパティレベルの遅延フェッチを使う場合(内部的にバイトコード処理をする場合)、fetch all propertiesを使うことでHibernateに遅延プロパティを速やかに(最初のクエリで)フェッチさせることができます。
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like '%cats%'
14.4. Forms of join syntax(結合構文の形式)
HQL supports two forms of association joining: implicit and explicit.
HQLは2つの関連結合形式をサポートします:暗黙的と明示的。
The queries shown in the previous section all use the explicit form where the join keyword is explicitly used in the from clause. This is the recommended form.
これまでのセクションでお見せした使い方はすべて明示的な形式で、from節で明示的にjoinキーワードを使っています。この形式をおすすめします。
The implicit form does not use the join keyword. Instead, the associations are "dereferenced" using dot-notation. implicit joins can appear in any of the HQL clauses.implicit join result in inner joins in the resulting SQL statement.
暗黙的フォームは、joinキーワードを使いません。代わりに、参照する関連にドット表記を使います。暗黙的結合は、さまざまなHQLに出てきます。暗黙的結合の結果は、SQLステートメントの内部結合結果です。
from Cat as cat where cat.mate.name like '%s%'
14.5. Refering to identifier property(識別子プロパティの参照)
There are, generally speaking, 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 entity does not define a non-identifier property named id.
特別なプロパティidは(小文字)エンティティをnon-identifier property named idで定義されていない提供されたエンティティの識別子プロパティを参照する際に使われます。
その実体がIDと呼ばれる非識別子資産を定めないならば、特別な資産(小文字の)IDは実体の識別子財産にリファレンスをつけるのに用いられるかもしれません。
? If the entity defines a named identifier property, you may use that property name.
もし、エンティティが識別子プロパティnamedで定義されていれば、プロパティ名を使用することは可能です。
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 rerference the identifier property.
合成識別子プロパティは同じnamingルールを満たしてください。もしエンティティはnon-identifierプロパティname id をもっている場合、合成識別子プロパティは定義されたnameだけを参照します。そうでなければ、特別なidプロパティは識別子プロパティを参照する際に使われます。
Note: this has changed significantly starting in version 3.2.2. In previous versions, idalways referred to the identifier property no matter what its actual name. A ramification of that decision was that non-identifier properties named id could never be referenced in Hibernate queries.
注意:これは3.2.2バージョンから変更されています。前のバージョンはactual nameを何であってもidはいつも識別子プロパティから参照されます。この結果の分岐は非識別子プロパティname idはHibernateクエリから絶対に参照されないからです。
14.6. The select clause(select節)
The select clause picks which objects and properties to return in the query result set. Consider:
select節は以下のようにどのオブジェクトと属性をクエリリザルトセットに返すかを選択します。:
select mate
from Cat as cat
inner join cat.mate as mate
The query will select mates of other Cats. Actually, you may express this query more compactly as:
上記のクエリは他のCatのmateを選択します。実際には次のように、より簡潔に表現できます。:
select cat.mate from Cat cat
Queries may 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 may return multiple objects and/or properties as an array of type Object[],
クエリは複数のオブジェクトと(または)プロパティを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,
もしくは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 as an actual typesafe Java object,
または、タイプセーフなJavaオブジェクトを返せます。
select new Family(mother, mate, offspr)
from DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr
assuming that the class Family has an appropriate constructor.
あるいはFamilyクラスが適切なコンストラクタを持っているとするならば、
You may assign aliases to selected expressions using as:
select節にasを使って別名をつけることもできます。
select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n
from Cat cat
This is most useful when used together with select new map:
select new mapと一緒に使うときに最も役立ちます:
select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n )
from Cat cat
This query returns a Map from aliases to selected values.
このクエリは別名からselectした値へMapを返します。
14.7. Aggregate functions(集約関数)
HQL queries may even return the results of aggregate functions on properties:
HQLのクエリはプロパティの集約関数の結果も返せます:
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 may use arithmetic operators, concatenation, and recognized SQL functions in the select clause:
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
The distinct and all keywords may be used and have the same semantics as in SQL.
SQLと同じ意味を持つdistinctとallキーワードを使うことができます。
select distinct cat.name from Cat cat
select count(distinct cat.name), count(cat) from Cat cat
14.8. Polymorphic queries(ポリモーフィックなクエリ)
A query like:
次のようなクエリ:
from Cat as cat
returns instances not only of Cat, but also of subclasses like DomesticCat. Hibernate queries may 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:
Catインスタンスだけではなく、DomesticCatのようなサブクラスも返されます。Hibernateクエリは どんなJavaクラスやインターフェイスもfrom節に入れることができます。クエリはそのクラスを拡張した、もしくはインターフェイスを実装した全ての永続クラスを返します。次のクエリは永続オブジェクトをすべて返します:
from java.lang.Object o
The interface Named might be implemented by various persistent classes:
Namedインターフェイスは様々な永続クラスによって実装されます。:
from Named n, Named m where n.name = m.name
Note that 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 can't call these queries using Query.scroll().)
最後の二つのクエリは、二つ以上のSQLSELECTを要求していることに注意してください。このことはorder by節がリザルトセット全体を正確には整列しないことを意味します(さらにそれは、Query.scroll()を使用してこれらのクエリを呼ぶことができないことを意味します。)。
14.9. The where clause(where節)
The where clause allows you to narrow the list of instances returned. If no alias exists, you may refer to properties by name:
where節は返されるインスタンスのリストを絞ることができます。もし別名がない場合、名前でプロパティを参照します。
from Cat where name='Fritz'
If there is an alias, use a qualified property name:
もし別名がある場合、修飾名を使ってください。
from Cat as cat where cat.name='Fritz'
returns instances of Cat named 'Fritz'.
名前が'Fritz'というCatのインスタンスを返します。
select foo
from Foo foo, Bar bar
where foo.startDate = bar.date
will return all instances of Foo for which there exists an instance of bar with a dateproperty equal to the startDate property of the Foo. Compound path expressions make the where clause extremely powerful. Consider:
上のHQLは、FooのstartDateプロパティと等しいdateプロパティを持ったbarインスタンスが存在する、すべてのFooインスタンスを返します。コンパウンドパス式(例えば「cat.mate.name」)はwhere節を非常に強力にします。注目:
from Cat cat where cat.mate.name is not null
This query translates to an SQL query with a table (inner) join. If you were to write something like
このクエリはテーブル結合(内部結合)を持つSQLクエリに変換されます。その代わりに以下のように書くと、
from Foo foo
where foo.bar.baz.customer.address.city is not null
you would end up with a query that would require four table joins in SQL.
もし上のクエリを記述したらクエリ内に4つのテーブル結合を必要とするSQLクエリに変換されます。
The = operator may 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 may be used to reference the unique identifier of an object. See Section 14.5, "Refering to identifier property" for more information.
id(小文字)は特別なプロパティであり、オブジェクトのユニークな識別子を参照するために使用できます。(さらに、そのプロパティ名を使用できます。) 詳しくはSection 14.5, "Refering to identifier property"を参照して下さい。
from Cat as cat where cat.id = 123
from Cat as cat where cat.mate.id = 69
The second query is efficient. No table join is required!
2番目のクエリは効率的です。テーブル結合が必要ありません!
Properties of composite identifiers may also be used. Suppose Person has a composite identifier consisting of country and medicareNumber. Again, see Section 14.5, "Refering to identifier property" for more information regarding referencing identifier properties.
また複合識別子のプロパティも使用できます。ここでPersonがcountryとmedicareNumberからなる複合識別子を持つと仮定します。またSection 14.5, "Refering to identifier property"を参照して下さい。
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 requires no table join.
もう一度言いますが、2番目のクエリにはテーブル結合が必要ありません。
Likewise, 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.
同様にclassは特別なプロパティであり、ポリモーフィックな永続化におけるインスタンスのdiscriminator値にアクセスします。where節に埋め込まれたJavaのクラス名はそのdiscriminator値に変換されます。
from Cat cat where cat.class = DomesticCat
You may also use components or composite user types, or properties of said component types. See ??? for more details.
またコンポーネントや複合ユーザ型(またそのコンポーネントのコンポーネントなど)のプロパティも指定できます。
An "any" type has the special properties id and class, allowing us to express a join in the following way (where AuditLog.item is a property mapped with <any>).
"any"型は特別なプロパティであるidとclassを持ち、以下の方法で結合を表現することを可能にします(AuditLog.itemは<any>でマッピングされたプロパティです)。
from AuditLog log, Payment payment
where log.item.class = 'Payment' and log.item.id = payment.id
Notice that log.item.class and payment.class would refer to the values of completely different database columns in the above query.
log.item.classとpayment.classが上記のクエリ中で全く異なるデータベースカラムの値を参照するということに注意してください。
14.10. Expressions(Expression式)
Expressions allowed in the where clause include most of the kind of things you could write in SQL:
QLのwhere節で記述することが出来る式のほとんどをHQLでも記述できます。:
? mathematical operators +, -, *, /
? binary comparison operators =, >=, <=, <>, !=, like
? logical operations and, or, not
? Parentheses ( ), indicating grouping
? in, not in, between, is null, is not null, is empty, is not empty, member of andnot member of
? "Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ... then ... else ... end
? string concatenation ...||... or concat(...,...)
? current_date(), current_time(), current_timestamp()
? second(...), minute(...), hour(...), day(...), month(...), year(...),
? Any function or operator defined by EJB-QL 3.0: substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()
? coalesce() and nullif()
? str() for converting numeric or temporal values to a readable string
? cast(... as ...), where the second argument is the name of a Hibernate type, andextract(... from ...) if ANSI cast() and extract() is supported by the underlying database
? the HQL index() function, that applies to aliases of a joined indexed collection
? HQL functions that take collection-valued path expressions: size(), minelement(), maxelement(), minindex(), maxindex(), along with the special elements() and indicesfunctions which may be quantified using some, all, exists, any, in.
? Any database-supported SQL scalar function like sign(), trunc(), rtrim(), sin()
? JDBC-style positional parameters ?
? named parameters :name, :start_date, :x1
? SQL literals 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0'
? Java public static final constants eg.Color.TABBY
in and between may be used as follows:
nとbetweenは以下のように使用できます。:
from DomesticCat cat where cat.name between 'A' and 'B'
from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
and the negated forms may be written
また、否定形で記述することもできます。
from DomesticCat cat where cat.name not between 'A' and 'B'
from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
Likewise, is null and is not null may be used to test for null values.
同様にis nullやis not nullはnull値をテストするために使用できます。
Booleans may be easily used in expressions by declaring HQL query substitutions in Hibernate configuration:
Hibernate設定ファイルでHQL query substitutionsを定義すれば、boolean値を式の中で簡単に使用できま。:
<property name="hibernate.query.substitutions">true 1, false 0</property>
This will replace the keywords true and false with the literals 1 and 0 in the translated SQL from this HQL:
こうすることで下記のHQLをSQLに変換するときにtrue,falseキーワードは1,0に置き換えられます。:
from Cat cat where cat.alive = true
You may test the size of a collection with the special property size, or the special size()function.
特別なプロパティsize、または特別な関数size()を使ってコレクションのサイズをテストできます。:
from Cat cat where cat.kittens.size > 0
from Cat cat where size(cat.kittens) > 0
For indexed collections, you may refer to the minimum and maximum indices usingminindex and maxindex functions. Similarly, you may refer to the minimum and maximum elements of a collection of basic type using the minelement and maxelementfunctions.
インデックス付きのコレクションでは、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
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).
コレクションの要素やインデックスのセット(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)
Note that these constructs - size, elements, indices, minindex, maxindex, minelement,maxelement - may only be used in the where clause in Hibernate3.
size,elements,indices, minindex,maxindex,minelement, maxelementはHibernate3のwhere節だけで利用可能であることに注意してください。
Elements of indexed collections (arrays, lists, maps) may be referred to by index (in a where clause only):
インデックス付きのコレクション(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
The expression inside [] may 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.
一対多関連や値のコレクションの要素に対しては、HQLは組み込みのindex()関数も用意しています。
select item, index(item) from Order order
join order.items item
where index(item) < 5
Scalar SQL functions supported by the underlying database may be used
ベースとなるデータベースがサポートしているスカラーSQL関数が使用できます
from DomesticCat cat where upper(cat.name) like 'FRI%'
If you are not yet convinced by all this, think how much longer and less readable the following query would be in SQL:
もしまだ全てを理解していないなら、下のクエリを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)
Hint: something like
ヒント: 例えばこのように出来ます。
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
)
14.11. The order by clause(order by節)
The list returned by a query may be ordered by any property of a returned class or components:
クエリが返すlistは、返されるクラスやコンポーネントの任意の属性によって並べ替えられます。:
from DomesticCat cat
order by cat.name asc, cat.weight desc, cat.birthdate
The optional asc or desc indicate ascending or descending order respectively.
オプションのascとdescはそれぞれ昇順か降順の整列を示します。
14.12. The group by clause(group by節)
A query that returns aggregate values may 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
A having clause is also allowed.
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)
SQL functions and aggregate functions are allowed in the having and order by clauses, if supported by the underlying database (eg. not in MySQL).
もし使用するデータベースがサポートしているなら、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
Note that neither the group by clause nor the order by clause may contain arithmetic expressions. Also note that Hibernate currently does not expand a grouped entity, so you can't write group by cat if all properties of cat are non-aggregated. You have to list all non-aggregated properties explicitly.
もし使用するデータベースがサポートしているなら、havingとorder by節でSQL関数と集約関数が使えます(例えばMySQLにはありません)。
14.13. Subqueries(サブクエリ)
For databases that support subselects, Hibernate supports subqueries within queries. A subquery must be surrounded by parentheses (often by an SQL aggregate function call). Even correlated subqueries (subqueries that refer to an alias in the outer query) are allowed.
サブセレクトをサポートするデータベースのため、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
Note that HQL subqueries may occur only in the select or where clauses.
HQLサブクエリは、selectまたはwhere節だけで使われることに注意してください。
Note that subqueries can also utilize row value constructor syntax. See Section 14.18, "Row value constructor syntax" for more details.
selectリストに複数の式を持つサブクエリには、タプルを使うことができます。詳細はSection 14.18, "Row value constructor syntax"を参照してください。
14.14. HQL examples(HQL例)
Hibernate queries can be quite powerful and complex. In fact, the power of the query language is one of Hibernate's main selling points. Here are some example queries very similar to queries that I used on a recent project. Note that most queries you will write are much simpler than these!
Hibernateクエリは非常に強力で複雑にできます。実際、クエリ言語の威力はHibernateの主要なセールスポイントの一つです。ここに最近のプロジェクトで使用したクエリと非常によく似た例があります。ほとんどのクエリはこれらの例より簡単に記述できることに注意してください!
The following query returns the order id, number of items and total value of the order for all unpaid orders for a particular customer and given minimum total value, ordering the results by total value. In determining the prices, it uses the current catalog. The resulting SQL query, against the ORDER, ORDER_LINE, PRODUCT, CATALOG and PRICEtables has four inner joins and an (uncorrelated) subselect.
以下のクエリは特定の顧客と与えられた最小の合計値に対する未払い注文の注文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
What a monster! Actually, in real life, I'm not very keen on subqueries, so my query was really more like this:
何て巨大なクエリなのでしょう! 普段私は副問い合わせをあまり使いません。したがって私のクエリは実際には以下のようになります。:
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
The next query counts the number of payments in each status, excluding all payments in the AWAITING_APPROVAL status where the most recent status change was made by the current user. It translates to an SQL query with two inner joins and a correlated subselect against the PAYMENT, PAYMENT_STATUS and PAYMENT_STATUS_CHANGEtables.
次のクエリは各ステータスの支払い数を数えます。ただしすべての支払いが現在の利用者による最新のステータス変更である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
If I would have mapped the statusChanges collection as a list, instead of a set, the query would have been much simpler to write.
もし私が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
The next query uses the MS SQL Server isNull() function to return all the accounts and unpaid payments for the organization to which the current user belongs. It translates to an SQL query with three inner joins, an outer join and a subselect against the ACCOUNT,PAYMENT, PAYMENT_STATUS, ACCOUNT_TYPE, ORGANIZATION and ORG_USER tables.
次のクエリは現在のユーザが所属する組織に対するアカウントおよび未払いの支払いをすべて返す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
For some databases, we would need to do away with the (correlated) subselect.
いくつかのデータベースについては、(関連させられた)副問い合わせの使用を避ける必要があるでしょう。
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
14.15. Bulk update and delete(大量のUpdateとDelete)
HQL now supports update, delete and insert ... select ... statements. See Section 13.4, "DML-style operations" for details.
HQLは今はupdateとdelete、insert ... select ...ステートメントをHQLに入れることをサポートしています。Section 13.4, "DML-style operations"に詳細があります。
14.16. Tips & Tricks(ヒントとトリック)
You can count the number of query results without actually returning them:
実際に結果を返さなくてもクエリの結果数を数えることができます。:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue()
To order a result by the size of a collection, use the following query:
コレクションのサイズにより結果を並べ替えるためには以下のクエリを使用します。:
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)
If your database supports subselects, you can place a condition upon selection size in the where clause of your query:
使用しているデータベースがサブセレクトをサポートする場合、クエリのwhere節でサイズによる選択条件を設定できます:
from User usr where size(usr.messages) >= 1
If your database doesn't support subselects, use the following query:
使用しているデータベースがサブセレクトをサポートしない場合は、次のクエリを使用してください:
select usr.id, usr.name
from User usr.name
join usr.messages msg
group by usr.id, usr.name
having count(msg) >= 1
As this solution can't return a User with zero messages because of the inner join, the following form is also useful:
内部結合をしているせいで上の解決法が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
Properties of a JavaBean can be bound to named query parameters:
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();
Collections are pageable by using the Query interface with a filter:
コレクションはフィルタ付きQueryインターフェイスを使用することでページをつけることができます。:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
Collection elements may 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" );
You can find the size of a collection without initializing it:
コレクションを初期化せずにコレクションのサイズを得ることができます。:
( (Integer) session.iterate("select count(*) from ....").next() ).intValue();
14.17. Components(コンポーネント)
Components might be used in just about every way that simple value types can be used in HQL queries. They can appear in the select clause:
コンポーネントはHQLクエリに簡単なvalue型を使われるすべての方法に使われます。これらはselect節で定義されます。
select p.name from from Person p
select p.name.first from from Person p
where the Person's name property is a component. Components can also be used in thewhere clause:
人の名前がプロパティがコンポーネントの場合。コンポーネントはwhere節にも使われます。
from from Person p where p.name = :name
from from Person p where p.name.first = :firstName
Components can also be used in the order by clause:
コンポーネントはorder by節にも使われます。
from from Person p order by p.name
from from Person p order by p.name.first
Another common use of components is in Section 14.18, "Row value constructor syntax".
他にもコンポーネントの一般的な使用はSection 14.18, "Row value constructor syntax"にも書いてあります。
14.18. Row value constructor syntax()
HQL supports the use of ANSI SQL row value constructor syntax (sometimes called tuplesyntax), 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:
HQLは基本的なデータベースはそれの概念をサポートしていなくても、ANSI SQL row valueコンストラクタ構文の使用をサポートしています。(たまにはtuple構文ともいいます。)ここで、私たちはコンポーネントに典型的にかかわる一般的なmulti-valued comparisonsを参考にしています。エンティティPersonを考察するとnameコンポーネントを定義します。
from Person p where p.name.first='John' and p.name.last='Jingleheimer-Schmidt'
That's valid syntax, although a little verbose. It is nice to make this a bit more concise and use row value constructor syntax:
少し冗長であるけれども、それは有効な構文です。もう少しを簡潔にして、row valueコンストラクタ構文を使うとよいでしょう:
from Person p where p.name=('John', 'Jingleheimer-Schmidt')
It can also be useful to specify this in the select clause:
これはselect節にも指定することが出来ます。
select p.name from from Person p
Another time using row value constructor syntax can be beneficial is when using subqueries needing to compare against multiple values:
row valueコンストラクタ構文の他の特典は複数valueに対する比較でサブクエリを使うときです。
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.
ここで、この構文を使うかどうか決めるときに考察してほしいのは、構文を使うクエリがメタデータにコンポーネントサブプロパティの指示に依存していることです。
No comments:
Post a Comment