EzJDBCで結合した時の自動バインディングの秘密
EzJDBCの自動バインディングの方法は前回の「EzJDBCの自動バインディングの秘密」で説明いたしました。
今回は、テーブルをJOINした結果をエンティティにマッピングする場合の自動バインディングについて説明します。以下の関係のテーブルを結合した結果を例に説明いたします。
【利用テーブル】
1.CUSTOMERテーブル プライマリーキー:ID
2.ORDERテーブル プライマリーキー:NO
3.ORDER_ITEMテーブル プライマリーキー:ORDER_NO, SEQ
4.ADDRESSテーブル プライマリーキー:ZIP_CODE【テーブル関係】
CUSTOMER : ORDER : ORDER_ITEM = 1 : n : m
CUSTOMER : ADDRESS = 1 : 1
EzJDBCでテーブルを結合した照会結果をEntityにマッピングするコードは下記のようになります。
1.EzJDBC#relationメソッドを利用しない場合
CUSTOMER CUS = new CUSTOMER();
Listlist = EzJDBC.froms(CUS).join(CS.ODR.ODI).join(CUS.ADR)
.where(CUS.name.like("Taka%")).find(Customer.class);
この時バイトコードエンハンスメントで作成されるバインド用ソースは以下の様になります。
public static List
getCustomerList(ResultSet resultSet) {
Listlist = new ArrayList ();
while(resultSet.next()) {
// Customerエンティティーを生成します
Customer customer = new Customer();
customer.id = resultSet.getInt(1);
customer.name = resultSet.getString(2);
customer.age = resultSet.getInt(3);
...
// Customerエンティティを結果Listに追加します
list.add(customer);// Orderエンティティーを生成します
Order order = new Order();
order.no = resultSet.getString(11);
order.orderDate = resultSet.getDate(12);
order.amount = resultSet.getInt(13);
...
// OrderエンティティをCustomerエンティティのorderListに追加します
customer.orderList.add(order);
// OrderItemエンティティーを生成します
OrderItem orderItem = new OrderItem();
orderItem.orderNo = resultSet.getString(21);
orderItem.seq = resultSet.getInt(22);
order.itemName = resultSet.getInt(23);
...
// OrderItemエンティティをOrderエンティティのorderItemListに追加します
order.orderItemList.add(orderItem);// Addressエンティティーを生成します
Address address = new Address();
address.zipCode = resultSet.getString(31);
...
// AddressエンティティをCustomerエンティティのaddressにセットします
customer.address = address;
}
return list;
}
上記コードは、照会結果の1レコード毎にCustomerエンティティを生成しマッピングしていきます。
つまり「照会結果のレコード数=Customerエンティティ数」となるため、重複したCustomerエンティティが結果Listに入っています。
where(CUS.name.like("Taka%"))の条件にあうCUSTOMERテーブルのデータが1レコードだとしても、
子テーブルであるORDERが1レコード、孫テーブルであるORDER_ITEMが5レコードあった場合は結果リストList
のサイズは5になるわけです。
次にEzJDBC#relationメソッドを利用した場合の結果を見てみましょう。
2.EzJDBC#relationメソッドを利用した場合
CUSTOMER CUS = new CUSTOMER();
Listlist = EzJDBC.froms(CUS).join(CS.ODR.ODI).join(CUS.ADR)
.where(CUS.name.like("Taka%")).relation().find(Customer.class);
この時バイトコードエンハンスメントで作成されるバインド用ソースは以下の様になります。
public static List
getCustomerList(ResultSet resultSet) {
// エンティティーの初期設定
Customer customer = null;
Order order = null;
OrderItem orderItem = null;
Address address = null;// Customerエンティティーリスト
Listlist = new ArrayList ();
while(resultSet.next()) {
// Customerテーブルのキーブレイクチェック
if(customer == null || customer.id != resultSet.getInt(1)) {
// Customerエンティティーを生成します
customer = new Customer();
customer.id = resultSet.getInt(1);
customer.name = resultSet.getString(2);
customer.age = resultSet.getInt(3);
...
// Customerエンティティを結果Listに追加します
list.add(customer);
// 子・孫エンティティを初期化します
order = null;
orderItem = null;
address = null;
}// Orderテーブルのキーブレイクチェック
if(order == null || !order.no.equals(resultSet.getString(11))) {
// Orderエンティティーを生成します
order = new Order();
order.no = resultSet.getString(11);
order.orderDate = resultSet.getDate(12);
order.amount = resultSet.getInt(13);
...
// OrderエンティティをCustomerエンティティのorderListに追加します
customer.orderList.add(order);
// OrderItemエンティティにnullをセット
orderItem = null;
}// OrdeItemrテーブルのキーブレイクチェック
if(orderItem == null || !orderItem.orderNo.eqauls(resultSet.getString(21)) ||
// OrderItemエンティティーを生成します
orderItem = new OrderItem();
orderItem.orderNo = resultSet.getString(21);
orderItem.seq = resultSet.getInt(22);
order.itemName = resultSet.getInt(23);
...
// OrderItemエンティティをOrderエンティティのorderItemListに追加します
order.orderItemList.add(orderItem);
}// Addressテーブルのキーブレイクチェック
if(address == null || !address.zipCode.equals(resultSet.getString(31))) {
// Addressエンティティーを生成します
Address address = new Address();
address.zipCode = resultSet.getString(31);
...
// AddressエンティティをCustomerエンティティのaddressにセットします
customer.address = address;
}
}
return list;
}
上記コードは、照会結果をCUSTOMERテーブルのキーで集約し、キーが変わった時のみCustomerエンティティを生成しマッピングしていきます。
つまり「照会結果のレコード数!=Customerエンティティ数」となります。
where(CUS.name.like("Taka%"))の条件にあうCUSTOMERテーブルのデータが1レコードだとして、
子テーブルであるORDERが1レコード、孫テーブルであるORDER_ITEMが5レコードあったとしても、結果リストList
つまりEzJDBC#relationの場合は結合(JOIN)した結果データをオブジェクトツリーとしてマッピングしてくれる機能は、こうやって実装されているのですね^^