17.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();
17.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> を使わなければなりません。