16.2. 名前付き SQL クエリ
名前付き SQL クエリはマッピングドキュメントで定義することができ、名前付き HQL クエリと全く同じ方法で呼ぶことができます。この場合、
addEntity()
を呼び出す必要は ありません。
<sql-query name="persons"> <return alias="person" class="eg.Person"/> SELECT person.NAME AS {person.name}, person.AGE AS {person.age}, person.SEX AS {person.sex} FROM PERSON person WHERE person.NAME LIKE :namePattern </sql-query>
List people = sess.getNamedQuery("persons") .setString("namePattern", namePattern) .setMaxResults(50) .list();
<return-join>
要素を使って関連を結合し、<load-collection>
要素を使ってコレクションを初期化するクエリを定義します。
<sql-query name="personsWith"> <return alias="person" class="eg.Person"/> <return-join alias="address" property="person.mailingAddress"/> SELECT person.NAME AS {person.name}, person.AGE AS {person.age}, person.SEX AS {person.sex}, address.STREET AS {address.street}, address.CITY AS {address.city}, address.STATE AS {address.state}, address.ZIP AS {address.zip} FROM PERSON person JOIN ADDRESS address ON person.ID = address.PERSON_ID AND address.TYPE='MAILING' WHERE person.NAME LIKE :namePattern </sql-query>
名前付き SQL クエリはスカラ値を返すこともできます。
<return-scalar>
要素を使って、列の別名と Hibernate の型を宣言しなければなりません:
<sql-query name="mySqlQuery"> <return-scalar column="name" type="string"/> <return-scalar column="age" type="long"/> SELECT p.NAME AS name, p.AGE AS age, FROM PERSON p WHERE p.NAME LIKE 'Hiber%' </sql-query>
リザルトセットのマッピング情報を
<resultset>
要素に外部化することができます。複数の名前付きクエリか setResultSetMapping()
API で再利用できます。
<resultset name="personAddress"> <return alias="person" class="eg.Person"/> <return-join alias="address" property="person.mailingAddress"/> </resultset> <sql-query name="personsWith" resultset-ref="personAddress"> SELECT person.NAME AS {person.name}, person.AGE AS {person.age}, person.SEX AS {person.sex}, address.STREET AS {address.street}, address.CITY AS {address.city}, address.STATE AS {address.state}, address.ZIP AS {address.zip} FROM PERSON person JOIN ADDRESS address ON person.ID = address.PERSON_ID AND address.TYPE='MAILING' WHERE person.NAME LIKE :namePattern </sql-query>
代わりに、hbm ファイル内のリザルトセットのマッピング情報を直接 Java コードで使用できます。
List cats = sess.createSQLQuery( "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id" ) .setResultSetMapping("catAndKitten") .list();
16.2.1. 列と列の別名を明示的に指定するために return-property を使う
Hibernate が別名を挿入できるようにするには、
{}
構文を使う代わりに、<return-property>
を使い、どの列の別名を使うのかを Hibernate に対して明示できます。
<sql-query name="mySqlQuery"> <return alias="person" class="eg.Person"> <return-property name="name" column="myName"/> <return-property name="age" column="myAge"/> <return-property name="sex" column="mySex"/> </return> SELECT person.NAME AS myName, person.AGE AS myAge, person.SEX AS mySex, FROM PERSON person WHERE person.NAME LIKE :name </sql-query>
<return-property>
は複数の列も扱えます。これは、複数列のプロパティをきめ細かく制御できないという、{}
構文の制限を解決します。
<sql-query name="organizationCurrentEmployments"> <return alias="emp" class="Employment"> <return-property name="salary"> <return-column name="VALUE"/> <return-column name="CURRENCY"/> </return-property> <return-property name="endDate" column="myEndDate"/> </return> SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate}, REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCY FROM EMPLOYMENT WHERE EMPLOYER = :id AND ENDDATE IS NULL ORDER BY STARTDATE ASC </sql-query>
この例では、挿入のための
{}
構文と組み合わせて、 <return-property>
を使いました。こうすることで、ユーザーは列とプロパティをどのように参照するかを選べます。
マッピングに discriminator が含まれている場合、 discriminator の列を指定するために、
<return-discriminator>
を使わなければなりません。