2005.05.22 · 技術と道具

S2DAOを試してみる

ゴールデンウィークにSeasar2を試してみましたが、引き続いて今日はS2DAOを試してみました。

我がThinkPadには、Oracle10gの試用版をインストールしてあるので、そこにGROUPとMEMBERの2つのテーブルを作成。中身のデータは、GROUPがモーニング娘。とかで、MEMBERが吉澤ひとみとか・・・。MEMBER.GROUP_IDは、GROUP.IDと関連しています。

(以下はEclipseの使用が前提の話です。)
さて、S2DAOですが、まずS2DAOのlibはs2-dao-1.0.26.jar、Seasar2のlibはめぼしいものすべてを、ビルドパスに加えます。次に、j2ee.dicon、dao.dicon、log4j.propertiesを、自分のワークスペースにコピー。これで、準備完了。

作らないといけないのは、JavaBeans、Dao、diconファイル、sqlファイルの4種類と、ドライバとなる実行プログラム。

JavaBeansは1テーブル1個ずつ作成。普通にgetter/setterを書いて、S2DAO用にアノテーションを書いていきます。ここが肝。N:1マッピングをする時は、JavaBeansのN側にアノテーションが必要です。

Daoも1テーブル1個ずつ。interfaceとして作ります。今回は、insert()、update()、delete()、get○○By○○()といったメソッドを作成(interfaceなのでメソッド定義だけ)。ここでもアノテーションをうまく書けば、SQLの自動生成も可能になります。
ちなみに、自動生成されないメソッドの場合は、Dao名_メソッド名.sqlというファイルを作り、その中にSQLを書いておけば、それだけでOK。

今回の実行プログラムは、MEMBER.GROUP_IDを指定して該当するMEMBER.NAMEと紐づくGROUP.NAMEを表示するもの(参照系)と、複数のMEMBERを1トランザクションで追加するもの(更新系)の2つを作りました。

参照系は、MemberDaoに追加したgetMemberByGroupId(int groupId)を呼び出してListを貰い、それを表示するように作りました。このgetMemberByGroupIdも、アノテーションでSQL自動生成可能。JavaBeansでN:1マッピングのアノテーションを書いてあるので、aMember.getGroupUnit().getName()といった感じで、関連先のGROUPテーブルに対応したJavaBeansであるGroupUnitが取得できます。

更新系は、実行プログラムがMemberAdderインタフェースを実装したサービス(VudAdder=美勇伝Adder)を呼び出し(DIする)、そのサービスがMemberDao#insert(Member member)を使って3人をMEMBERテーブルに追加するというもの。
3人分の追加が1トランザクションになるようにしたいので、diconファイルで、3人のMemberを追加するサービスであるVudAdderにj2ee.requiredTxをaspectとして追加しました。また、VudAdderが使用するDaoをDIするため、コンストラクタインジェクションの設定をしてあります。

MemberAdder.diconファイル

XML
GroupUnitDao
MemberDao
j2ee.requiredTx

さて、そんな感じで、S2DAOの実験は成功したのですが、ハマった点について。

何も考えずに、1つのサービスを処理するために、diconファイルをあちこちで読んでS2Containerをあちこちで作ったりすると、トランザクションがバラバラになります。
あちこちでS2Containerを作ってもトランザクションさえなければ普通に動きますので要注意です。サービスを呼び出すレイヤのところあたりでS2Containerを作ってサービスをgetComponent()し、そのサービス内で使うコンポーネントは、DIしてあげる(VudAdderがコンストラクタインジェクションでDIされているように・・・)のが良いようです。しかし、どっかで誰かがgetComponent()しなければならないものなんですかね?それ自体もDIされたいんですけどね・・・。要調査。

あと、気になる点。
N:1マッピングで1の方を引っ張ってきますが、逆にN側をINSERTする時に1側のオブジェクトを入れておいたからといって自動で外部KEYが設定されるわけではないです。N側に1側をセットする時に、1側のKEYをN側の外部KEYプロパティにセットするとかの工夫が必要です。例えば、Member#setGroupUnit(GroupUnit gu)において、this.groupUnit = guだけでなく、this.groupUnitId = gu.getId()しておくという話。

総括としては、慣れれば簡単便利に使えそうです。ただ、N:1マッピングのあたりの話や、S2DAOでは1:Nがマッピングされないといった話もあって、オブジェクト指向を本気でやる場合には、力不足の感は否めません。本気にオブジェクト指向しないケースなら、うまく使えそうな気がします。

2005/05/22 17:40
← いま一度、Zen Microを。
Hibernateを試してみる →
井上 研一
経済産業省推進資格ITコーディネータとして中小企業のDX・AI活用の現場で伴走支援を行う。「ITCプロセスガイドライン4.0」および「中小企業向けAI活用ガイド」執筆メンバー。著書・講演多数。ITエンジニアとして25年以上の実務経験。AI導入の実務に10年以上携わる。自ら開発したAIサービス「Gen2Go」が北九州発!新商品創出事業の認定を受ける。2026年4月より北九州市立大学大学院マネジメント研究科の学生としての顔も持つ。

本サイトおよびブログに掲載している内容は、特に明記のない限り、井上研一個人の見解に基づくものです。所属・関与する組織、団体、企業、研究会等の公式見解を示すものではありません。