[Seasar-user:11003] Re: [S2Dao]SQLファイルを使わずにUNIONを実行したいです

kubo [E-MAIL ADDRESS DELETED]
2007年 10月 15日 (月) 16:47:01 JST


久保です。

> 2)SQLファイルでは対応できない(と思う)。
> 
> キーワードでLIKE検索するのですが、そのキーワードが一つではないので、
> LIKE部分をプログラムでループさせて作成する必要があり、
> SQLファイルでは対応できません(と思っている)。
> 

「不定数の条件作成」に関して

全く同じような要件を経験したことがあったので、
自分の場合の解決方法を情報共有させて頂きます。
(DBFluteを使っていることが前提ですので参考程度にということで)


自分の場合は、以下のような要件と解決案がありました。

【要件】
一つのテキストボックスでユーザが「空白区切りでキーワードを入力」し、
その区切られたキーワード郡である列に中間一致のAND条件を不定数でつなげる

   例. ユーザ入力-- [Seasar S2Dao DBFlute]
       条件 -- [Seasarを含む、かつ、S2Daoを含む、かつ、DBFluteを含む]

  ※カタログサイトの検索画面とかで多い仕様かと思います。


【解決案】

<A>
上限が有る場合は、上限文の分岐を準備する

  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  /*IF pmb.keyword1 != null*/KEYWORD = /*pmb.keyword1*/'Seasar'/*END*/
  /*IF pmb.keyword2 != null*/KEYWORD = /*pmb.keyword2*/'S2Dao'/*END*/
  /*IF pmb.keyword3 != null*/KEYWORD = /*pmb.keyword3*/'DBFlute'/*END*/
  ...(以下上限まで)
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

  → 上限が無ければOUT。かつ、かっこ悪い。

<B>
DBFluteのLikeSearchの機能を使う。

  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  String keywords = [ユーザ入力文字列そのまま] "Seasar S2Dao DBFlute"
  LikeSearchOption likeSearchOption = new LikeSearchOption();
  likeSearchOption.likeContain().splitBySpace();
  cb.query().setKeyword_LikeSearch(keywords, likeSearchOption);

    ↓

  KEYWORD like '%Seasar%'
    and KEYWORD like '%S2Dao%'
    and KEYWORD like '%DBFlute%'
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

  → ConditionBean限定

<C>
外だしSQLで埋め込み変数コメントを使って不定数条件を組み立てる
(要はプログラムで生成したSQLを実行)

  ※既にひがさんと今田さんがコメントされています。

  → SQLインジェクション対策は自分で行う

<D>
外だしSQLで埋め込み変数コメントを使って不定数条件を組み立てる
(但しBind変数をしっかり使う)

S2Daoは、埋め込み変数コメントにBind変数コメントを埋め込んで
使うことはできません。これはS2DaoがSQLのBind変数を静的に解析して
いるからです。(これはPerformanceを考慮しているので当然の動き)

DBFluteでは、埋め込み変数コメントにBind変数コメントを埋め込んでで
利用するモードを設けています。
Daoのメソッドに以下のようなアノテーションを付けると、
そのメソッドが利用するSQL文を動的に再度解析して、
埋め込み変数コメント内のBind変数コメントを検知して利用します。

  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
  @OutsideSql(dynamicAnalysis=true)
  List<Xxx> selectListXxx();
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

  → 動的解析コストがかかります。
    (目に見えるほどではないですが、ミリ秒単位で計ると少し遅くなります)。


実際の開発では、大抵は「B」で済んで、ちょっと難しいものは「D」で実現しました。
S2Daoのみ利用の場合は、「A」か「C」が簡単ですが、独自で拡張して
「D」を実現するのもアリかとは思います(S2Daoの内部構造の知識が必要)。





DBFlute補足:
「Unionの話」に関して

Unionの話は、上記の不定数の条件から派生しているのかなと思いますが、
不定数のUNIONは上記の「D」で代用できます。
同じテーブル同士のUNION限定であれば、
ConditionBeanでも不定数Unionを実現することはできます。






Seasar-user メーリングリストの案内