DBFlute: S2Daoの一部機能を抑制【重要】

これはまだ未リリースの次バージョン「0.8.2」の話です。

{Java/C#}: 
S2Daoの機能でDBFluteとしてはセキュリティホールになるものを抑制
https://www.seasar.org/issues/browse/DBFLUTE-351

【背景】
DBFlutedbflute.diconで提供するS2Daoにおいて、
S2Daoの機能を(ほぼ)全てサポートしていました。
その理由は:
・もともとS2Daoの自動生成ツールとして始まった
・S2Daoをリスペクトしている
・いざってときのS2Dao
ということから頑張ってサポートしていましたが、
DBFluteのポリシーに合わない、そして、セキュリティホールに
なってしまう機能が幾つか存在します。

DBFluteの主なポリシーとして
・DB変更に強い
・安全であること
というのがありますが、Daoインターフェースでの
S2Daoの一部の機能は上記のポリシーに反します。

そこで将来「今DBFluteを知らない人たち」にも
もっと使ってもらうことを考えた時に、
「DBFluteのポリシーを薄めてしまうこれらの機能」
は抑制されていた方がよいかと
判断しました。悩みました。しかし決断しました。

また、0.8.1は非常に良いレベルまで達したバージョンであり、
そういうバージョンを出すことができたというのも一つの理由です。
(どうしてもバージョンアップできない人も困らないように)

ちなみにこの一部の機能は、DBFluteのドキュメントにも
Exampleにもどこにも書いていない機能です。
(S2Daoを使ったことのある人しか知らない機能です)

【内容】
詳しくはJIRAの方に書いてありますが、
ここでも少し解説します。

/= = = = = = = = = = = = = = = = = = 
A. Queryアノテーション
B. DTOによるSQL自動生成
C. ARGSアノテーションによるSQL自動生成
= = = = = = = = = =/

つまりは、S2DaoSQL自動生成機能です。
これらはFK先全てを結合してしまうため、
DBFluteのEntityとは徹底して相性が悪いです。
パフォーマンス劣化の温床です。
(実際問題になってたプロジェクトをみたことあります)
ConditionBeanは、
「明示的に選択してない関連テーブルは取得しない」
という安全設計になっています。
「B」と「C」は完全にConditionBeanで代替できます。
「A」の部分文字列埋め込みはDB変更に弱いです。
これらのことから抑制対象としています。

/= = = = = = = = = = = = = = = = = = 
D. SQLアノテーション
= = = = = = = = = =/

DB変更に弱いです。
OutsideSqlTestの対象にはなりません。
DBFluteの「CBと外だしSQLの二つ!?」というポリシー
からも外れます。(無用な選択肢は増やしたくない)
これらのことから抑制対象としています。

但し、この機能は今回抑制対象にした機能の中でも
一番利用されている可能性が高いと思われます。
(正直、他の機能はDBFlute上でそれらを使ってることは
 ほぼあり得ないかと考えております)
なので、互換モードがあります。
torque.isCompatibleS2DaoSQLAnnotationValid = true
で、SQLアノテーションが利用できます(これはJava版のみ)。
しかしながら、このフラグをtrueにすることはお奨めしません。
(しっかり外だしSQLで書いた方が良いからです)
OutsideSqlTestの対象にしたくないSQLの場合でも、
http://d.hatena.ne.jp/jflute/20080616/1213596145
のように対象外にすることは可能ですので。

/= = = = = = = = = = = = = = = = = = 
E. 外だしSQLでの関連マッピング
= = = = = = = = = =/

外だしSQLでも「select abc as abc_0」というように
Relnoを付与して、many-to-oneの関連Entityに
マッピングする機能です。
これが一番DBFluteと相性が悪い機能で、かつ、業務的に不要な
機能なので、現状使っている人を想像できません。
(自動生成するたびにRELNOが変わってしまう可能性があるので)
厳密には、
「Behavior経由の外だしSQLでの関連マッピング」
を抑制しております。
DBFluteでは外だしSQLの結果は「フラット構造」が基本です。

そして、これを抑制すると実は、
「外だしSQLでDomainEntityを使ったときの検索」
(テーブルと1:1でRELKEYがたくさん付与されてるEntity)
が、非常にパフォーマンスが良くなります(内部処理が向上)。
(S2Daoで同じことした場合に比べてかなり速くなります)

【補足】
これにより、Daoインターフェースに定義して
利用可能な機能は、
・Daoインターフェースでのプロシージャアノテーション
・Daoインターフェースでの外だしSQL
となります。どちらもDBFluteで代替出来る機能であり、
基本的に使う必要のない機能ですが、今回抑制対象ではありません。

dbflute.diconで実現しているS2Daoが上記のような挙動になるだけで、
別途dao.diconを用意して、通常のS2Daoのクラスを利用するDaoを
作成した場合は無関係です。