ResultSetMapping(Contstructor Result Mapping) の使い方
JPA ResultSetMappingのメモ
DB からデータを取得するとき、2つのテーブルを結合してそれぞれのテーブルから
データを絞って取得したいときはよくあること。
例えば↓みたいなテーブルがあって
艦船
艦名 | 工廠 |
---|---|
大和 | 1 |
陸奥 | 2 |
海風 | 4 |
工廠
ID | 工廠名 |
---|---|
1 | 呉 |
2 | 横須賀 |
3 | 佐世保 |
4 | 舞鶴 |
こんな結果が欲しい
結果表
艦名 | 工廠 |
---|---|
大和 | 呉 |
陸奥 | 横須賀 |
海風 | 舞鶴 |
Native SQL、JPQL 的には
SELECT 艦名, 工廠名 FROM 艦船 INNER JOIN 工廠 ON 艦船.工廠 = 工廠.ID
しかし普通に実行した結果だと Object 型のリストになる。
(上記だと、3レコード分 Object のリストで、カラム分で更に2つのリスト)
これをわかりやすく自分で定義したクラスで取得したい時は、ResultSetMapping を使えば可能となる。
以下のような設定
●eclipselonk-orm.xml
<sql-result-set-mapping name="buttleShip" > <constructor-result target-class="hoge.fuge.ButtleShip"> <column name="shipName" /> ←ここと <column name="arsenalName"/> </constructor-result> </sql-result-set-mapping> <named-native-query name="findButtleShip" result-set-mapping="buttleShip"> <query> <![CDATA[ SELECT 艦名 shipName, ←ここは合わせないとエラる 工廠 arsenalName FROM 艦船 INNER JOIN 工廠 ON 艦船.工廠 = 工廠.ID ]]> </query> </named-native-query>
●POJO
@Getter @Setter @AllArgsConstructor public class ButtleShip { private String shipName; private String arsenalName; }
(lombok 使った記述にしてます)
ちなみに、SQLの実行時に戻りとなる POJO のクラスを指定しないと Objectで返ってくる
素の記述だと、これに時に設定となるかな
entityManager.createNamedQuery( queryName, resultClass );
POJO ではコンストラクタを指定しないと、SQL 実行時にエラーになる
使用している仕組みが Constructor Result Mapping というだけあって、コンストラクタで値を設定しているもよう
Constructor Result Mappings は JPA 2.1 から使えるようになったみたいなので、
それ以前の場合は注意が必要
参考にしたのはここ