アーキテクトのためのチュートリアル

アーキテクトが DBFlute を扱う上での必要なノウハウや開発時にやるべきことをまとめたページです。

[jfluteのつぶやき] *2017/01/01
DBFlute-1.1.2 をリリースしました。

アーキテクトの実装スタイル

六つのトップエントリ

DBFluteの紹介
まず最初はこちら
DBFluteの環境
初回セットアップアップグレードChangeLog など
自動生成ツールとしてのDBFlute
自動生成の玄関、DBFluteタスクDBFluteクライアント など
O/RマッパーとしてのDBFlute
Behavior, ConditionBean, Entity, OutsideSql など
DBMSごとの取扱い
MySQL, PostgreSQL, Oracle, DB2, SQLServer など
DBFluteプロパティ
DBFluteの設定、たくさんの dfprop と環境ごと切り替えなど

四つの環境構築

初回セットアップ
DBFluteのセットアップ *最初の第一歩
アップグレード
DBFluteのアップグレード *バージョンを上げよう
EMecha
EMecha (Eclipse Plugin) *とりあえず全員インストール
Maven
Maven (Maven Plugin) *玄人向け

一つの大仕事

DB環境構築の自動化
ReplaceSchema *テーブル作成&テストデータ登録

二つのやり方

よくあるSQL
ConditionBean *タイプセーフ&目的指向
ちょいムズSQL
外だしSQL(OutsideSql) *2Way-SQL

三つのクラス

Entity
データ(レコード)を格納
Behavior
DBアクセスの入り口 (DIコンポーネント)
ConditionBean
検索条件の組み立て

七つのDBFluteタスク

ReplaceSchema
テーブル作成データ登録データ整合性チェック ※DB環境構築の自動化
JDBC
DBからメタデータを取得 ※自動生成する前に
Doc
ドキュメントを自動生成 (SchemaHTML, HistoryHTML) ※JDBC叩いてから
Generate
Entityクラス(など)を自動生成 ※JDBC叩いてから
Sql2Entity
外だしSQLのEntity, ParameterBeanを自動生成 ※外だしSQL書いたら
OutsideSqlTest
外だしSQL(OutsideSql)を2WaySQLとして一括実行 ※SQLの一括チェック
Manage
様々なDBFlute管理タスクを実行 ※本当に様々

五つの現場フィット

アプリ実装の全体最適
共通カラム区分値業務的one-to-one排他制御Where句 など
プロジェクト構成対応
追加スキーマ (AdditionalSchema)複数DBアプリ外だしSQL など
実行時共通要件の実現
シーケンスキャッシュSQLログの取得例外ハンドリング など
DBFlute利用のサポート
外だしSQLのタイトル、自動生成後の自動更新など
非推奨な構造フォロー
PKのないinsert複合主キーの対策 など

八つのタレントたち

SchemaHTML
なんとかHTML御三家、自動生成されるテーブル定義ドキュメント
HistoryHTML
DB差分御三家、なんとかHTML御三家 自動生成されるDB変更履歴
SchemaSyncCheck
DB差分御三家、DBスキーマ同期チェック ※とあるDBとDBの差分チェック
AlterCheck
DB差分御三家、alter文の整合性チェック ※前のDB + alter = 最新create
CraftDiff
手作り差分チェック、DB差分の項目を独自のSQLで自由に拡張
LoadDataReverse
DB上のデータをエクセルへダンプ、ReplaceSchemaデータと連携
PropertiesHTML
なんとかHTML御三家、propertiesファイルの差分チェック
ProcedureCall
ストアドプロシージャもタイプセーフ呼び出し

九つの小人たち

DBFluteConfig
DBFluteのランタイムに関する微調整コンフィグ(設定)
キャメルケースコード補完
キャメルケースの大文字部分を狙い打つ! ※ConditionBeanでは必須!?
サロゲートキーと複合主キー
サロゲートキーつけてナチュラルキーには複合ユニーク制約
ページング検索
そもそもページング検索とは?できる限りの分析
Eclipseフォーマッター
コードフォーマット、Eclipseのデフォルトフォーマット定義は使わない
Oracle配列・構造体
がんばりすぎ
DIコンテナごとの取扱い
SeasarとDBFluteのコラボレーション
フィードバック
質問だってフィードバック! ※わからなければ、気軽にMLで聞いてください
DBFluteハンズオン
DBFluteとJavaプログラミングを同時に学べるハンズオン教材

必要なノウハウ

アーキテクトは、実装部分だけでなくDBFluteの環境周りや設定周りなど全体を把握する必要があります。 DBFluteを探っている人、これから使う人、問わずに必要なノウハウを得るためのエントリです。

DBFluteの概念・役割

開発の効率化のためにDBFlute利用を推進する、提案されてきたDBFlute利用の許可判断をするなどの場合、 直接は利用(実装)しないとしてもある程度の "概念と役割" を理解しておく必要があります。

DBFluteのインフラ情報

DBFluteを採用することが可能なのか?インフラ的な視点を事前に把握しておくことが大事です。 DBFluteを使う場合に最適な環境は?という視点からも把握しておくことは大事です。

自動生成ツールとしてのDBFlute

DBFluteと触れ合うとき、一番最初に出会うのは自動生成ツールとしてのDBFluteです。 DBFluteはO/Rマッパでもありながら、自動生成ツールそのものと言えます。

O/RマッパーとしてのDBFlute

DBFluteのメインの部分です。どのようなアーキテクチャなのか?どのように実装するのか? ディベロッパーへの横展開のためにも、O/RマッパーとしてのDBFluteを把握する必要があります。

また、ディベロッパー視点からのDBFluteを知ることが、"O/RマッパーとしてのDBFlute" を知ることの近道でもあります。(ディベロッパーのための)チュートリアルに必ず目を通しておきましょう。

DBMSごとの取扱い

DBMSによって扱いに若干の違いが生まれます。利用するDBMSのページに目を通しておきましょう。

DBFluteプロパティ

最適なDBFluteプロパティを設定することで、その現場にフィットしたDBFluteにすることができます。 また、環境ごとに dfprop を差し替えることもできます(結合環境用の ReplaceSchema など)。

デフォルトfalseだが、ほとんどtrueでOKのプロパティに関する特集コラムがあります。

開発時にやるべきこと

アーキテクトが開発時にやるべきことは以下の通りです。

DBFluteの利用ポリシー決め

"DBFluteをどう使うか?"、"作業が発生したときに誰がどう行うか?" 事前に決められるものは決めておきましょう。この後の項目の内容を参考に開発がスムーズに進むようにポリシーを考えてみて下さい。

ReplaceSchemaの利用有無

大きな判断の一つとして、ReplaceSchemaを利用するかどうか?というのがあります。 DB変更への耐性を強くするのであれば、利用を強く推奨します。 DB変更を迅速にディベロッパーの開発用ローカルDBに反映させるために、ReplaceSchemaが役に立つでしょう。

特にテストデータの管理は重要です。DBFluteは "DB変更に強い" を特徴としていますが、 プログラムだけがDB変更に強くても足りないと考えていて、テストデータもDB変更に強くないと実際にはDB変更のコストは高いまま です。テストデータの管理が曖昧で散在していると、いざDB変更したときにテストデータを修正する手間が膨大になってしまいます。 ReplaceSchemaのようなツールを使って、 しっかりテストデータも管理しておくことで本当に意味でDB変更に強い と言えるでしょう。

ReplaceSchemaの情報は、Alto DBFlute でも大きく取り上げられています。

Alto DBFlute

DBFluteのセットアップ

DBFluteのセットアップは一つのプロジェクトに付き一回だけ行います。 開発が始まる前のDB設計がおおよそ固まった時点で行い、生成されたクラスを "バージョン管理システム" (SVNなど)に登録をしてディベロッパーが利用できるようにします。

全体最適のための設定

DBFluteは全体最適を行う様々な 現場フィットな機能 があります。プロジェクト要件と機能が一致するのであれば、事前にしっかりと設定をしてディベロッパーに横展開することお奨めします。

設定した後は、ディベロッパーの実装に影響のあるものはしっかりと周知します。例えば "共通カラムは自動設定されるので insert や update のときに気にしなくていいですよ" とか "区分値を設定したのでこういうメソッド使って下さいね" などなど。そういった情報はメールや口頭で伝えるだけでなく、いつでも参照できるようにプロジェクト内の 情報共有システム (Wikiなど)に掲載しておくと良いでしょう。

ディベロッパーへの横展開

DBFluteに限ったことではないですが、開発が本格化する前にディベロッパーに実装スキルを習得してもらう必要があります。 "各自勉強しておくように" というのも悪くはありませんが、勉強会などでディベロッパーたちがスキルを共有 できるような形にしておくことで、スキル習得の効率も上がりますし、開発が始まってからの ディベロッパー同士の情報交換によるスキル向上 も望めます。

ディベロッパーのためのチュートリアル というページを用意していますので、ディベロッパーには必ず(一度は)このページを読んでもらうようにして下さい。 調べ物をするときのエントリページにもなりますので、ブラウザのブックマークに登録してもらうと良いでしょう。

DB変更時の再自動生成

DB変更が発生したら、もろもろ再自動生成します。

DBFluteのアップグレード

新しいDBFluteがリリースされたときに、DBFluteをアップグレードするか否かの決定とアップグレード作業をする必要があります。 移行時の注意 を必ず読んでスムーズに最新版のDBFluteをディベロッパーが利用できるようにしましょう。

特集コラム

デフォルトfalseだが、ほとんどtrueでOKのプロパティ

DBFluteとしては、どうしてもデフォルトで true にしづらいプロパティがあります。万が一のケースでトラブりやすいと考えられるものです。 レアケースはいえ true にできないもの。

例えば、区分値において、区分値解決メソッドとCDef型の引数のメソッドがあれば、ネイティヴ型のメソッドは既に不要なものです。 ですが、DBFluteの区分値定義に存在していなくてDB上にだけ存在する "隠れ区分値" のようなものがあった場合(別システムで利用されるとか)、そして、そのアプリでもその値が検索したり設定したりするようなことがある場合、ネイティヴ型のメソッドがないと扱うことができません。 そんなことまずあり得ないと思われますが、万が一そういう現場があるかもしれないと考えると true にできないのです。

感覚値ですが9割以上の現場で問答無用でネイティヴ型のメソッドは削除して良いでしょう。 そういった感じのプロパティをここで幾つか特集したいと思います。(本当にOKか確認はしましょう)

区分値のネイティヴ型のメソッドの削除と例外検知
隠れ区分値がなければ。(そもそもそんな区分値があるとややこしい)
空文字は null に変換して登録・更新
空文字に意味を持たせないで良いのであれば。(そもそも持たせるとややこしい)
別名(和名)の設定やDBコメントの扱い
DBコメントの中に、どういう形式で別名(和名)を含めるかを確認して設定しましょう。 isEntityJavaDocDbCommentValid に関しては、別名の設定に関わらず、とりあえず true にして自動生成してコンパイルエラーがなければOKという感じです。(ぜひDBコメントは活用したい)
外だしSQLのコメントは必須に
OutsideSqlTestタスクで、外だしSQLのコメントの有無をチェックできます。(コメント必須)
ストアドプロシージャを使うのであれば
プロシージャ使うならとりあえず設定するでOK。(実際に使ってみて何かあれば微調整で良い)
DBMSの挙動に関わらずテーブル名を大文字に
主に MySQL にて、"テーブル名大文字小文字区別なしモード" にするとメタデータが小文字になってしまうので。 (もちろんもともと小文字でいいのなら関係ないですが、もし、ERDなどドキュメントが大文字なのであれば、SchemaHTML 上のテーブル名も合わせて大文字にしたいので)

EntityとDTOとの詰め替えは地道に

あえて強く言います

検索したEntityのデータを画面用のDTOに詰め替えする時や、またはその逆の時など、リフレクションでプロパティ名が同じ項目の値を自動で詰め替えしてくれるツールが世の中に多くありますが... DBFluteとの相性は最悪で、決して使うべきではありません(Beanなんとかとか)

と、ちょっとあえて強く言いましたが、DBFluteでは全くオススメしません。なぜでしょうか?

リフレクション詰め替えとの相性は最悪

DBFluteは、DB変更に強いをテーマにしていますが、もしリフレクションでの詰め替えをやってしまうと、その影響範囲がコンパイルでは検知できなくなります。 名前が変わったりカラムが削除されたりしても、本当に影響があるのかどうかは実際に画面を動かしてみて、その項目の値を目視するまではわからないのです。

画面DTOを作成して詰め替えをするのはとても良いことです。JSPなどから直接 Entity を参照してしまうと、それこそコンパイルセーフの恩恵に預かれません。 逆にいうと、画面DTOまで作っておきながらリフレクションで詰め替えるのは本末転倒とも言えます。

完全に DBFlute のポリシーと反する機能であることがわかります。

予期せぬトラブルのオンパレード

また、DBFluteに限らず、このリフレクションを使ったやり方が多くのトラブルを生み出してきたのを見てきました。 項目名に処理が依存するということは、コンパイルセーフなJavaの中にメタプログラミングが紛れ込んでるとも言えます。 その気軽なメタプログラミングの扱いが、予期せぬ失敗を生み出すことがあります。 しかも、そのトラブルはとても原因を特定しづらく、デバッグに非常に時間がかかりやすいものであることが多いです。

さらには、カラムの利用状況を調べたいとおもうときに、Eclipseでいう "ctrl + shift + G" による呼び出しプログラムの検索が効かなくなります。これは地味ながら何気につらいことです。誰がそのカラムを get したり set したりしているのかがとてもわかりにくくなります。

費用対効果で考えると...地道が一番

昨今のIDE(Eclipseなど)ではメソッドの補完などが充実していて、例えばキャメルケースのコード補完などを使ってリズムよく書いていけば、ベタに書いたとしてもさほど書くコストは発生しません。

目の前の数分のコストをケチって、将来のややこしいバグを生み出す可能性をプログラムに埋め込むのは、あまり得策とは思えないのです。 DB項目を画面にマッピングする処理というのは、業務の根幹のロジックですから、そのはしっかりと書きたいところです。