2010/05/28

既存のStrutsプロジェクトへS2DAOを適用してみる

Seasar2を使ったプロジェクトを経験した。
全体としては開発ツールとしての完成度も考えると
.NETの「型指定されたDataSet」には遠く及ばないが
データベースに関しての操作は非常に楽であった。
また、動的にSQLを組み立てるのはSQLコメントの
使い方さえ覚えてしまえば簡単。

経験したプロジェクトはSeasar2の良さを
あますところなく殺す、独自のフレームワークを
作られていてほとんど意味が無かった上に
プロジェクトそのものの進め方がでたらめ
だったので超大失敗プロジェクトだったが。

さて、以前Strutsを用いたシステムがあるのでこれに
S2DAOだけを適用してみる。
SAStrutsは使用しない。
struts-configファイルが不要になるなどのメリットは大きいが
そんな機能は利用しないので。

基本的にJavaのフレームワークは
・jarファイルをコピーして入れる
・設定ファイルを書く
この程度で済むはずなのでそれほど構える必要はない。


Seasar2は component(要するにクラス) として定義されたものを管理対象とする
のが基本である。
Seasar2が管理対象とするクラスはアプリケーションの中のどれなのか、
を定義ファイルで指定する必要がある。
※SMARTデプロイという自動 component 登録機能を利用するなら設定ファイルは不要。

■まず環境(Environment)
1.S2DAOは s2-dao-1.0.51.zip をダウンロード
2.また、定義ファイルの差し替え機能を利用したいのでSeasar2.4もダウンロード。
※なぜかS2DAOのダウンロードには2.3しか含まれていない。

・S2DAOのlibフォルダにあるファイルを全てWEB-INF/libへコピー
・Seasar2.4のlibフォルダにあるファイルを全てWEB-INF/libへコピー
同じ名前でバージョン違いのファイルは、古い方を削除
(例えばlog4j-1.2.8.jar log4j-1.2.13.jarなら1.2.8を消す)
・S2DAO、Seasar2.4のresourcesフォルダにあるdiconファイル、
log4jファイルを元プロジェクトのs2resources(新たに作成する)にコピー
・s2resourcesフォルダの中身をクラスパスに含めるように、
ビルドパスの設定でソースフォルダとする

「libのjarファイル(hsqldb.jar以外)とsrcのj2ee.dicon(Seasar2.4の場合はjdbc.dicon)を CLASSPATHにとおせば、S2Daoを実行できます。」
と書いてあるのでこれでよいはず。

■dao.dicon は定義ファイルの差し替えで変更する
設定を変更する必要がある。なぜならSQLファイルの文字コードがデフォルトではJISAutoDetectだからだ。
元々のStrutsプロジェクトはワークスペースのデフォルトをUTF-8にしている。
1.dao.diconはs2daoのjarから内容をコピーして cust-s2dao.dicon として s2resourcesにコピー
jarファイルは単なるZIPファイルなので拡張子を変えればすぐに抜き出せる。

<component class="org.seasar.dao.impl.DaoMetaDataFactoryImpl">
<property name="sqlFileEncoding">"utf-8"</property>
</component>


設定は上記のようにした。

2.さらに定義ファイルを差し替えるために、s2container.diconを作成。
実際はEclipseのChuraプラグインで生成されたファイルをコピーして来た。

<component class="org.seasar.framework.container.factory.SimplePathResolver">
<initmethod name="addRealPath">
<arg>"dao.dicon"</arg>
<arg>"cust-s2dao.dicon"</arg>
</initmethod>
</component>

上記内容を<components>タグの間に追加。

■Oracleへの接続設定
Seasat2.4ならj2ee.diconではなくjdbc.diconらしいので、
中身を見てみると既にサンプルがコメントとして入っていた。
H2をコメントアウトしてOracleのコメントを外し、サーバー、ユーザ等をセット

■JavaBean
Emp_Mst用のJavaBeanを作成する。

1.publicフィールドに対応しているハズなので、アクセサは不要。
カラム数分のフィールドを宣言すればよい。
「ECODE」というカラムなら ecode という名前のフィールドにすれば良い。
データタイプとのマッピングはドキュメントを参照した。
2.Tableアノテーションで実際のテーブル名を指定

■S2DAO用のコードを記述(Implementation)
■Dao
NameAsYouLikeDao
の命名規則に従ってEmpMstDaoを作成。

1.使用するJavaBeanをS2Daoアノテーションで指定
2.社員番号とパスワードだけを指定する、getEmpメソッドを宣言。
3.SQLをメソッドにアノテーションで指定
4.パラメータ用の変数 [メソッド名+ "_ARGS"] getEmp_ARGSフィールドを宣言

■Seasar2で利用するコンポーネント定義用のdiconファイル
components.diconを新規作成し、作成したEmpMstDaoインターフェースを設定
これはDAOインターフェースの数だけ登録が必要なようだ。

SMARTデプロイの規約に従っていれば設定ファイルは不要だが、
既存のアプリケーションに適用する場合はパッケージ構造を
簡単には変更できない事も多いので、これで良いと思われる。

×Seasar2のWEBアプリ設定はしてはならない
app.diconとS2Servletの指定をしてしまうと、
リクエストがそちらに乗っ取られてしまうのか、Strutsが動作しなくなる。

S2DAOやSeasar2.4を解凍したフォルダには
exampleのプロジェクトがあるので
Eclipseにインポートしてしまえば
動作させるためのコードがすぐに参照できる。

■動作させる(Run)

1.S2Containerを初期化
2.DAOコンポーネント(インスタンス)を取得
3.DAOメソッドの呼び出し
4.S2Containerの破棄

これだけで良い。

S2Container s2 = S2ContainerFactory.create("components.dicon");
s2.init();
try {
     EmpMstDao dao = (EmpMstDao) s2.getComponent(EmpMstDao.class);
     model.beans.EmpMst emp = dao.getEmp(userID, password);
} finally {
     s2.destroy();
}
このような感じ。
これだけでDBへ接続して、SQLアノテーションで指定した
SQLが実行され、オブジェクトにマッピングされ、
自動的に接続が閉じられる。
接続はデフォルトでコネクションプールが使われている。
(Tomcat等のコネクションプール設定は不要)

■SQLを別ファイルに

public String getEmp_ARGS = "ecode, password";
@Sql("select・・・・")
public EmpMst getEmp(int ecode, String password);

となっていたのを変更してみる。

public String getEmp_ARGS = "ecode, password";
@SqlFile
public EmpMst getEmp(int ecode, String password);

として、SQLを「EmpMstDao_getEmp.sql」というファイルに
移動してDAOと同じパッケージに置くだけ。

■SQLを自動生成
SQLのWhere条件やOrderByをQueryアノテーションで指定すれば
自動的にSQLを生成してくれる。

public String getEmp_ARGS = "ecode, password";
@Query("WHERE ecode=/*ecode*/ and password=/*password*/ ORDER BY name")
public EmpMst getEmp(int ecode, String password);

SQLファイルそのものが不要になる。
デフォルトのメソッド命名規則で、insert や update に対応するメソッド名があるが
それ以外のメソッド名にすれば、検索として扱われる。
戻り値が使用するBeanおよびそのリスト、配列であればよい。


■問題点(Problems)
このプロジェクトではすでに POIライブラリを利用しており、
その機能が動作しなくなったので、Seasar2.4に含まれていた
POIライブラリは削除して、元々利用していた jar ファイルに戻した。

若干とまどった部分はあったが、あっさりと適用できた。
全てのプロジェクトがそうだとは思わないが、
jarファイルのバージョンによる不整合がPOIライブラリしか出なかったので、
問題は少なかったように思う。

■終わりに(Finale)
ITプロジェクトは時間が全てコストに跳ね返る。
Seasar2を適用したい、以前のプロジェクトがStrutsを利用していた、
さあ、SAStrutsだ、と短絡的に考えない事も重要。
特に今回のようにS2DAOを利用して得するのはプログラマーだけ。
ユーザーにはほとんどメリットが無い。
多少保守性があがるといったメリットはあるかもしれないが
現時点では分からない。
こんなコストを請求してはならない。

2010/04/04

指示待ち人間

そういう気持ちが湧き上がる事も多々ある。

「私は指示待ち人間ですから言われた事しかできません」

勘違いしてはならない。

指示待ち人間は言われた事すら出来ない。

考えるのをやめてしまったから。

言われた事が理解できない。

でも指示待ち人間になりたい時がある。
対症療法しかできなくなった人が上の立場に居た時は。