DBFlute-0.9.6.1 リリース

@DBFlute, Java
DBFlute-0.9.6.1をリリースしました。
同時にEMecha-0.4.7もリリースされています。
EMechaを利用してアップグレードする場合は、
最新バージョンのEMechaでの利用をお奨めします。

「対応課題の一覧(Wikiページ)」
「DBFluteの移行」
「DBFlute-0.9.6から0.9.6.1への移行時の注意」

※DBFluteモジュールはEMechaからダウンロード可能です。

主な目玉:

o 同梱しているH2とDerbyのバージョンをアップ
o SQLServerでCBのUnionとPagingの同時利用をサポート
o char(3)のカラムに2桁のデータを格納するようなDBの対処
#
# 同梱しているH2とDerbyのバージョンをアップ
#
H2とDerbyに関しては、気付いた時点で最新バージョンを
同梱するようにしているのですが、H2が1.1系から1.2系に
アップしていることに注意です。

1.2系で作成したDBに1.1のJAR経由ではアクセスできないようです。
実際に、新しいDBFluteでReplaceSchemaしたDBに対して、
アプリが1.1のJAR経由でアクセスしたら「テーブルがみつからない」
という類いの例外が発生しました。
(ちなみに、1.1で作成されているDBに1.2のJAR経由はOKでした)

アプリの方でどうしても1.2系にアップできないのであれば、
DBFluteが組み込んでいるH2を差し替えて下さい。
#
# SQLServerでCBのUnionとPagingの同時利用をサポート
#
もともと、SQLServerでのConditionBeanでのunionとpagingの同時利用は
サポートされていませんでした(実現上の不都合で)。ですが、なんとか頑張って、
実現出来るようにしたので気にする必要はもうありません。
#
# char(3)のカラムに2桁のデータを格納するようなDBの対処
#
まず、前提としてはchar(3)のカラムに2桁のデータを格納するような
DB設計は、基本的にやめることをお奨めします。良いことないので。
2桁のデータが入るなら、それは正確なデータ型はvarcharです。
インフラ的にレコード長の調整でどうしても固定長にしたいのならば、
やはりそのデータを2桁じゃなく3桁にするべきです。
コードの場合、大抵は略称のような形になると思いますが、3文字で略称に
すれば良いだけです。どうしてもできないなら、せめてアンダースコアを
入れて3文字にするようにしましょう。

char(3)のカラムに2桁のデータを格納するようなDBの特徴を説明します。
カラムに'AB 'という値で登録されているとき、その値をselectすると:

 MySQL/H2: 'AB'
 他のDB: 'AB '

 ※MySQLINNODBにて
 ※登録したときが'AB'か'AB 'かについてはどちらも結果変わらず

という結果になります(実際に試してみてそうなった)。
DBによって変わるというちょっとやっかいな状況です。
さらに、select時に検索条件値が'AB'という値の場合:

 Oracle: NO HIT
 他のDB: HIT

これまたややこしい。。。
ここに依存しているとDB移行が発生した時にトラブりやすいです。
さらには、アプリとDB間でのやり取りだけでなく、
アプリ内で扱うときに、端っこの空白はちょっとしたきっかけで
トリムされやすいものです。コードにトリムする必要はないとは
わかっていても、もしも「一律トリム」みたいな処理がどっかに
あったら、その時点でどんな動きするかわかりません。
そんなことを気にするくらいなら、varcharにするかchar(3)で
しっかり3桁入れるようにしてしまえば良い話です。

と、言っても「もう変えられません」というような現場も多いことでしょう。
そこでDBFluteでは、検索条件で設定された'AB'を自動的に'AB 'に
するような処理(空白埋め)を、オプションで実現できるようにしました。
(検索条件による差異が一番問題になりやすいので)
#
# @littleAdjustmentMap.dfprop
#

# NONE(default), EXCEPTION, RFILL, LFILL
; shortCharHandlingMode = RFILL
このように設定すると、ConditionBeanでの条件設定値とParameterBeanでの
条件設定値において「そのカラムがchar型であることがわかる場合に限り」
その処理が施されます。char型であるかどうかを判定するというのは、
ConditionBeanではなんてことないことなので問題ありません。
(但し、自動生成時に決定するのでアプリ起動中に型変更しても反映されない)
ParameterBeanがちょとややこしいです。ParameterBeanのプロパティは
厳密にはどのカラムに対するプロパティなのかは判定できません。
そこで、以下のようなオプションでその関連付けをできるようにしました。
-- !!Integer memberId:ref(MEMBER)!!
-- !!Date birthdateFrom:ref(MEMBER.BIRTHDATE)!!
「ref(テーブル名)」は、そのプロパティが指定されたテーブルの中の
カラムであることを示し、カラム名はプロパティ名で判定します。
カラム名の判定はアンダースコアの違いを吸収します。
「ref(テーブル名.カラム名)」は、豪快にそのプロパティの関連を示します。
こうすることで、char型であることを判定できます。

ちなみに、この「refオプション」ですが、この機能に関わらず利用可能です。
カラムにエリアス名(和名)やコメントが定義されていて場合に、それを拾って、
ParameterBeanのJavaDocコメントに展開されるようになります。
無理に利用しなくても良いと思いますが、良く再利用されるSQLで様々な
ディベロッパーが関わるような場合は、やっておくと良いかもしれません。
この「shortCharHandlingMode」ですが、他には:
「NONE(default), EXCEPTION, LFILL」があります。

NONEは今まで通り(特に何もしない)。

LFILLは左に埋めるということであまり活躍しないと思いますが、
どうしてもプロジェクトで左空白埋めが必要になったときに。

EXCEPTIONはちょっとまた趣向が違っていて、char(3)のカラムに
2桁のデータ'AB'が検索条件として設定されて場合に例外になります。
char(3)のカラムで絶対に3桁のデータ入るという場合に、
間違って2桁のデータを入れる人がいないかどうかをチェックできます。
ただ、そんなに強いチェックではではないので、本当にそういうことで
問題が発生したときにチェックをONにしてテストを全部動かしてみる
みたいな場合に利用すると良いでしょう。
#
# まとめ
#
以前に比べて、一ヶ月の間での課題が減りました。
できれば今年最後のリリースにしたいですね。