Daoについての考察

2011/07/04 9:36 PM

 

データベースのからむアプリケーションを開発するとき、僕が気を付けていること

テーブル数が5個でも、機能数が10を超えるならば、以下のことを避けるようにする。

  1. SQLを文字列としてプログラムで組み立てる
  2. DBで検索したデータを一列ずつオブジェクトにセットする

これらは、

  • セキュリティホールを作ってしまう(SQLインジェクションなど)
  • デバッグ効率が低下する(実行しないとどんなSQLになるか分からない)
  • 似たようなソースが多くなる(言わずもがな)

などといったヤバい状況を作る元となる。
機能は減ることはなく、運用しながら増えていくもの、変わっていくものだから、上記のような組み方を最初にしてはいけない。

で、どうするかというと、まず、O/Rマッピングツールなり、Daoなりをもつフレームワークが使えるかを検討する。

この時のポイントは、

  1. 案件として、ツールが使えるか、自前で作らなくてはいけないか
  2. 使えるとして、習得する時間・コストがあるか

である。
2番目で注意しなくてはいけないのは、開発初期にメンバーの学習期間が必要だから、ツールを使わない、という政策で始まってしまうと、たいてい後が詰まって死ぬハメになる(「後」が開発後期なのか、修正の時なのかはケースバイケース)こと。

さて、晴れてツールもしくはフレームワークを使えるとして、選定のポイントは、

  1. プリペアドなSQLを別ファイルとして置いておけるか
  2. 関連したテーブルも取得できるか(Lazy loadingも含め)
  3. マッピングの際に、列名⇔メンバ名が、それぞれに相応しい命名規則が保てるか

であると考えている。

特に1番目は重要で、SQLが単体で存在することは、デバッグ時の効率を左右することだと思っている。
そのままDBマネジメントツールに貼りつけて実行出来るため、該当箇所まで画面を叩かなくて良いから。
なんだかんだ言って、SQLを直接触れることは効率の面で重要なのだ。

2番目は、S2Dao、Hibernateでは実装があるが、S2JDBCには無い。
(Eager Loadingは欲しいな)

3番目はDBはDBらしい命名規則、JavaはJavaらしい命名規則で、自動的に変換されることだ。気分の問題といえばそれまでだが、気分は重要。

個人的には、S2JDBCがベター。
僕は、Seasar2フレームワークが使えるなら、これを選択する。

  1. 書かないことがバグを少なくするという考えに基づいていて、Daoクラスで記述すべき処理がほとんど無い。
  2. 最大の特徴である、「流れるようなインターフェース」は、定型的なクエリには強い。
  3. SQLファイルをDaoクラス名+メソッド名のファイル名で外に置けること、
     ファイル中のパラメータをJava側のプロパティ名のコメントで記述できること、
     単体テスト用の値を書いておけること、
     パラメータの値でSQLを条件分岐できること(where句など超便利)がよい。
  4. S2では、Eclipseのプラグインを入れると、テーブルを右クリックしてCRUDのスキャッフォルドを作れる。
     これを拡張してアプリケーションを作る。これに慣れるとC#のスキャッフォルドが超貧弱に見える。

また、初期学習コストで敬遠されて、Daoを作ったことがある。

S2Dao(当時)のSQLファイル外置きの便利さを知っているから、機能限定(条件分岐はnullのみ)ながら対応した。以下のようなポイントを押さえた。

  1. テーブルごとにDaoを用意(そうでなくてもよい)。
  2. SQLファイルは外部ファイル。
  3. クラス名+メソッド名のSQLファイル。
  4. ファクトリにコネクションとXxxDao.classを渡すと、初期化されたDaoインスタンスが取得できる。
  5. SQLファイル内には、メソッドのアノテーションをコメント化して、パラメータとして記述する。
  6. SQLファイル内のパラメータによる条件分岐はnull、空文字判定のみ。
  7. メソッドの引数をアノテーションで記述し、ファイル読み込み時に、SQLファイル内のコメント化されたパラメータと引き当てる。
  8. 引数の値自体は、SQL実行時に順番を合わせてパラメータとして渡す。
  9. 検索系のクエリの場合は、検索されたレコードの列名と、イントロスペクトしたXxxクラスのメンバ名を引き当て、インスタンスに代入、リストに入れて返す。

要するに、SQL生成処理、検索・実行処理、オブジェクトへの代入処理をひとまとめにすることで、
クライアントプログラマは、必要なメソッドの最低限の実装(空にはできなかった)、SQL、アノテーションを書けば使えるようにしたのだった。

こんなSQLとメソッドになる。

SQLファイル:UserMasterDao_selectUserByDeptId.sql

Daoクラス:UserMasterDaoクラスのselectUserByDeptIdメソッド

クライアントクラス:UserMasterLogic.java

また、このアプリケーションは、Webのリクエストも自動的にオブジェクトに代入するようにしてある。

ただ、開発当初は、非常に多くの時間を費やしてしまった。

開発当初200程度だったSQLは、運用開始後2年間で機能拡張を重ね、400個を超えた。
拡張の要望に意欲的に応えられたのが幸いである。



コメントはまだありません

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを書く

WordPress Themes