2009/02/19(Thu) 00:02:55 編集(投稿者)
2009/02/19(Thu) 00:01:40 編集(投稿者)
2009/02/19(Thu) 00:01:24 編集(投稿者)
はじめまして。
私の場合はみきぬさんややじゅさんと同じかな?
今のプロジェクトではJavaで、Spring+Struts+Hibernateって環境です。
Struts配下のActionから検索条件を引数に持つServiceのメソッドが呼ばれ、その中で条件分岐を行い、like条件用のDaoのメソッドか、
=検索用のDaoのメソッドが呼ばれます。
ビジネスロジックやデータアクセス層はUIから分離されているってのは常套手段だし、UIで直にSQL文生成ってのは避けた方がよいと思います。
O/Rマッパーってたいていは単にオブジェクトとテーブルのマッピングを行うだけではなく、SQL生成用の仕組みが用意されていると思います。
Hibernateの場合はCriteriaってのがそれで、επιστημηさんが試していらっしゃるようなことができるようになっています。
どのような構造になっているか研究してみてはいかがでしょうか?
とはいいつつO/Rマッパー嫌いな私は、DaoでもSQL生成せずにストアド呼んじゃいたいところですけれど。
>最も簡単な方法はSQL文が必要なタイミングで、条件を網羅しながら文字列連結でWhere句を構築することだと思います。
これはDynamicSQL(動的SQL)と呼ばれる、あまり好ましくないとされる手法で、MSなんかはヤメテーヤメテーと連呼してます。
あと、対応しているRDBMSであればPrepared Statementを使用するべきかなあ。
例えばユーザー名での部分一致検索か、ユーザーIDでの完全一致での検索を行いたい場合。
DECLARE @CONDITION_TYPE bit;
DECLARE @USER_NAME varchar(20);
DECLARE @USER_ID int;
SET @USER_NAME = '%' + REPLACE(@USER_NAME, '%', '%%') + '%';
SELECT *
FROM WANKUMA_USER
WHERE (1 = @CONDITION_TYPE AND USER_NAME LIKE @USER_NAME) OR (0 = @CONDITION_TYPE AND USER_ID = @USER_ID);
こんな感じで組んでしまえば、検索条件が異なる場合でもひとつの静的SQLですんだりもします。
DECLARE @USER_NAME varchar(20);
DECLARE @USER_ID int;
IF(@USER_NAME IS NOT NULL)
BEGIN
SET @USER_NAME = '%' + REPLACE(@USER_NAME, '%', '%%') + '%';
END;
SELECT *
FROM WANKUMA_USER
WHERE (@USER_NAME IS NOT NULL AND USER_NAME LIKE @USER_NAME) OR (@USER_ID IS NOT NULL AND USER_ID = @USER_ID)
でもいけたかなあ?
条件が複雑になると組むのもデバッグも大変になるので、素直に分けたほうがいいとは思いますけれど。
※コードは適当なので感じだけつかんでもらえれば。。LIKEのメタ文字は%だけじゃなかったと思うし。
※※投稿なれてなくて編集ばっかでごめんなさい。。