2-4 チケット情報を表示しよう
この節からはO/RマッッピングツールのHibernateを使用したサンプルが掲載されています。マッピングの設定が面倒くさそうですが、それさえやってしまえば、データクラス自体はすっきりします。Middlegenというツールも興味深いので、近々試してみようと思っています。
Springの設定ファイルで、sessionFactoryのhibernate.show_sqlプロパティをtrueにしているため、サンプルを動かすと実行されたSQL文が表示されます。そのため、「予約済みのチケットを取得する」際に、どのようなSQL文が実行されて、どのようにオブジェクトが生成されるかを追ってみました。
まず、TicketDaoImplオブジェクトから、userIdが渡された上で、以下のような呼び出しが行なわれます。
public class TicketDaoImpl extends HibernateDaoSupport implements TicketDao { public List getBookedTicketList(Integer userId) { return getHibernateTemplate().find( " FROM Ticket AS ticket INNER JOIN FETCH ticket.event AS event " + " INNER JOIN FETCH ticket.rank AS rank WHERE ticket.reservation.user.userId = ? ", userId); } }
この結果、TicketクラスのオブジェクトがList形式で返ってきます。Ticketクラスには、Rank/Eventクラスのメンバー変数を保持していて、HQLでINNER FETCHしているので、それらも同時に生成されるようです。それをやるために、以下のようなSQL文が実行されていました。
select ticket0_.TICKET_ID as TICKET1_3_0_, event1_.EVENT_ID as EVENT1_0_1_, rank2_.RANK_ID as RANK1_1_2_, ticket0_.RANK_ID as RANK2_3_0_, ticket0_.EVENT_ID as EVENT3_3_0_, event1_.NAME as NAME0_1_, event1_.DATE as DATE0_1_, rank2_.NAME as NAME1_2_, rank2_.PRICE as PRICE1_2_, rank2_.EVENT_ID as EVENT4_1_2_ from ticket ticket0_ inner join event event1_ on ticket0_.EVENT_ID=event1_.EVENT_ID inner join rank rank2_ on ticket0_.RANK_ID=rank2_.RANK_ID, reservation reservatio3_ where ticket0_.TICKET_ID=reservatio3_.RESERVATION_ID and reservatio3_.USER_ID=?
HQLでticket.reservation.user.userIdとやると、それについても自動的に外部結合してくれています。さらにこのあと、取得した件数分だけ、別のSQL文が実行されていました。
select reservatio0_.RESERVATION_ID as RESERVAT1_2_4_, reservatio0_.TIMESTAMP as TIMESTAMP2_4_, reservatio0_.USER_ID as USER3_2_4_, ticket1_.TICKET_ID as TICKET1_3_0_, ticket1_.RANK_ID as RANK2_3_0_, ticket1_.EVENT_ID as EVENT3_3_0_, rank2_.RANK_ID as RANK1_1_1_, rank2_.NAME as NAME1_1_, rank2_.PRICE as PRICE1_1_, rank2_.EVENT_ID as EVENT4_1_1_, event3_.EVENT_ID as EVENT1_0_2_, event3_.NAME as NAME0_2_, event3_.DATE as DATE0_2_, user4_.USER_ID as USER1_4_3_, user4_.NAME as NAME4_3_ from reservation reservatio0_ inner join ticket ticket1_ on reservatio0_.RESERVATION_ID=ticket1_.TICKET_ID left outer join rank rank2_ on ticket1_.RANK_ID=rank2_.RANK_ID left outer join event event3_ on ticket1_.EVENT_ID=event3_.EVENT_ID left outer join user user4_ on reservatio0_.USER_ID=user4_.USER_ID where reservatio0_.RESERVATION_ID=?
これは、Ticketクラスのメンバー変数であるReservationクラスのオブジェクトを生成するのに使われていて、なぜこれが実行されたかというと、Ticket.hbm.xmlの中で、
<!-- bi-directional one-to-one association to Reservation --> <one-to-one name="reservation" class="model.Reservation" outer-join="auto" />
というように、outer-joinプロパティをautoに指定しているからなのではないかと考えられます。
この二つ目のSQL結果は、一つ目のSQL結果と重複している情報も取得しているような気がして、無駄な処理のような感じもしましたが、いずれにせよ、もうしばらくHibernateの作法を学んでからではないと何とも言えません。