今度は、HibernateのSessionオブジェクトを操作する代わりに、S2ではおなじみのアノテーションを用いた設定を行ってみましょう。S2のアノテーションについては何度も説明していますが、これはS2独自のstatic final型の変数を用いた設定の仕組みのことをいい、JDK5.0のそれとは別物です。
S2Hibernateで用意されているアノテーションは、以下に示すBEAN・HQL・ARGS・PROPERTYの4種類があります。
DAOと関連付けられるDTOクラスを設定します
(例) |
public static final Class BEAN = Account.class; |
“(メソッド名)_HQL”という変数名を持つString型の変数にHibernateで実行するHQL文を設定します。
(例)同じカテゴリーの小遣い帳の明細(Accountオブジェクト)を取得する |
public static final String getAccountByCategory_ARGS = |
DAOインターフェイスのメソッドに設定されている引数の名称を設定します。このとき“maxResults”と“firstResult”という名称が、それぞれデータを取得する件数とデータ取得の開始行を表す予約語となっているため、それらの値をメソッドの引数とする場合には、引数の名称を必ずこれに合わせる必要があります。
また、このアノテーションに設定された引数名がDTOのプロパティ名と同じである場合は、自動的にこれらがwhere句に追加されます。
(例1)ID番号をもとにaccountテーブルのデータをAccountオブジェクトとして取得する |
public static final String getAccount_ARGS = "id"; |
また、引数名に不等号をつけると、where句が不等号をつけた状態で生成されます。
(例2)amountの値が、ある数より大きいものだけを取得する(0以上にすれば収入の分だけ取得できる) |
public static final String getIncomeAccounts_ARGS = "amount >"; |
テーブルのカラム名とDTOのプロパティ名が異なる場合にARGS用います。HQL文である値の範囲を制限する場合などに適しています。
(例)金額がfromExpenseからtoExpenseまでの範囲にあるaccountテーブルのデータを取得する |
public static final String getExpenseAccounts_PROPERTY = "amount > |
では、これらのアノテーションにより、どのようにしてDBアクセスが行われるのかを紹介しましょう。まずは金額ある範囲にある支出についてaccountテーブルから取得してみましょう。
まずDAOインターフェイスをリスト11のように作成します。ここではHQL・ARGSの各アノテーションを用いています。これによりamountプロパティの値がfromExpenseからtoExpenseの範囲にあるAccountオブジェクトを取得することができます。そしてこの実装クラスは作成せずに、リスト12のようにして実行します。結果はリスト13のようになります。この間Sessionオブジェクトには全くふれずにデータを取得する処理を行うことができました。
ちなみに、この処理を実行するにあたってdiconファイルをリスト14のように作成しました。アスペクトの設定としてs2hibernate3.interceptorが追加されています。これはs2hibernate3.diconに設定されているもので、アノテーションの解釈とDBアクセスを可能に必要なものです。
リスト11 DAOインターフェイス(AccountDao.java) |
package myfirst.hibernate; |
リスト12 DBアクセスによりAccountオブジェクトを取得 |
S2Container container = S2ContainerFactory.create( "diconファイルのパス" ); |
|
リスト14 diconファイルの内容(account.dicon) |
<?xml version="1.0" encoding="Shift_JIS"?> |
SELECT以外のINSERT、UPDATE、DELETEについては、アノテーションすら設定せずに処理を実行することができます。ではそれぞれの処理をどのようにして行うかというと、メソッドの名称によってどんな処理を行えばよいのかを決定します。メソッドの引数はDTO、戻り値はvoidであることが条件です。
注意すべきとこととしては、これに関するドキュメントでの記述と実際の処理とが一部で食い違っているところがあるということです。筆者が確かめたところでは、UPDATEを行うメソッドは「update,merge」で始まる名称を持つメソッドに限定されるという点です。これについてドキュメントでは「update,modify,store」で始まる名称を持つメソッドはUPDATE処理が自動的に行われる旨が記述されています。これについては改善を望みたいところです。また、INSERTを行うメソッドはinsertで始まる名称もその対象になります。詳細は、付属ドキュメントの「メソッドの定義」を参照してください。
DAOインターフェイスとINSERT処理の例をリスト15、リスト16にそれぞれ示します。アノテーションが無かったら、一見してDBアクセスをしているように感じないところですが、これもS2HibernateとHibernateによるO/Rマッピングのおかげといえるでしょう。
リスト15 DAOインターフェイス(AccountDao.java) |
package myfirst.hibernate; |
Category c = new Category(); |
今回はS2でHibernateを利用できるようにするS2Hibernateを紹介しました。Hibernateをバーション2から同3に移行する場合には、再ビルドやAPIの変更などの注意が必要であるものの、新規に使い始める場合には、開発者がSessionオブジェクトにふれなくてもよいなどの利点があります。Hibernateのスキルがある方はぜひ試してみてください。
次回からはWeb層に関連するプロダクトを紹介します。はじめは、非常に良く知られているフレームワークStrutsを利用できるようにするS2Strutsをご紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.