DBFluteをできるだけ簡単に説明してみる
「DBFluteとは何か」と思って調べてみたら「DBFluteの紹介の時点で長すぎっ!!」って思った人向け。 いつも説明に困るのでまとめておく。
DBFluteとは、
です。
DBFluteの特徴
O/Rマッパーとして
- データベースのメタ情報を元にコードを自動生成し、SQL発行をタイプセーフに行うことができる。
- 手書きのSQL(外だしSQLと呼んでいる)も、対応するコードを生成してタイプセーフに実行。
- 生成されるコードはGeneration Gapパターン。
- JDBC APIにしか依存しない。JPAは使わない。独自のトランザクション管理もない。
- データベースのテーブル構造のまま、Javaから操作できるようにするだけ。
- O/Rマッパーとは言えないのかも。その分シンプルかつ強力。
- マッピング設定などは不要で、テーブルがそのままクラスになり、カラムがフィールドとなる。
- 外部キーから関連の多重度を推測し、適切なフィールドを追加してくれる(1:Nならば1側にList
を、N側にTを)。
- データベースのテーブル構造に対応するSQL生成コードが生成される。逆に言うと、構造上正しくないSQLが発行できない。
データベース周りのツールとして
データベースに関する様々なツール(タスクと呼ばれる)がある。
- O/Rマッピング用コード生成ツール(jdbc, generate, sql2entity, doc, manage regenerate)
- 既存のデータベースにJDBCで接続し、メタ情報を元にコードを生成する。
- 異常なまでに細かい沢山のカスタマイズ項目があるが、慣れるまでは無視して問題ない。
- データベーススキーマを作成する(ReplaceSchema)
- その他多数
- 「旧スキーマ+ALTER文=新スキーマ」であることをデータベースメタ情報をチェックして検証してくれるAlterCheck
- テーブルデータをExcelシートに吐き出すLoadDataReverseとかいろいろ
DBFluteの主要クラス
DBFluteを使ってDBアクセスするコードを書くにあたり、以下の3つを押さえておくこと。
- Entity
- レコードの値を保持するクラス。テーブルと1:1で対応する。
- SELECT結果の戻り値として、またINSERT/UPDATEのパラメータを詰めるために使用する。
- ConditionBean (CB)
- クエリの組み立てに使用するクラス。これもテーブルと1:1で対応する。
- Behavior (Bhv)
利用例
DBFluteを使ってのCRUDは以下のようになる。DBを操作するためのメソッドが生成されており、文字列でSQLを組み立てる箇所が一切ないことに注目。
public class ProductRepositoryTest { @Inject private ProductBhv productBhv; @Test public void selectRow() { ProductCB cb = productBhv.newMyConditionBean(); cb.query().setProductCode_Equal("XXXXX"); Product product = productBhv.selectEntity(cb); assertThat(product.getProductCode(), is("XXXXX")); } @Test public void selectRows() { ProductCB cb = productBhv.newMyConditionBean(); cb.query().setProductName_LikePrefix("iPad"); List<Product> products = productBhv.selectList(cb); assertThat(products.stream().map(Product::getProductName).collect(toList()), hasItems("iPad", "iPad Mini", "iPad Air")); } @Test public void selectJoin() { ProductCB cb = val.newMyConditionBean(); cb.query().setProductCode_Equal("XXXXX"); cb.setupSelect_Manufacture(); Product product = productBhv.selectEntity(cb); assertThat(product.getManufacture().getName(), is("Foxconn")); } @Test public void insert() { Product product = new Product(); product.setProductCode("ZZZZZ"); product.setProductName("iPad Nano"); productBhv.insert(product); ProductCB cb = new ProductCB(); cb.query().setProductName_LikePrefix("iPad"); assertThat(productBhv.selectCount(cb), is(4)); } @Test public void update() { Product product = new Product(); product.setProductCode("ZZZZZ"); product.setProductName("iPad Micro"); productBhv.update(product); assertThat(productBhv.selectByPKValue("ZZZZZ").getProductName(), is("iPad Micro")); } @Test public void delete() { Product product = new Product(); product.setProductCode("ZZZZZ"); product.setProductName("iPad Micro"); productBhv.delete(product); assertThat(productBhv.selectByPKValue("ZZZZZ"), is(nullValue())); } }
ここで使った以外にも、ConditionBeanでは様々なSQLが発行できる。詳しく知るにはConditionBeanの機能を参照のこと。
困ったときは
- DBFluteのドキュメントを見る http://dbflute.seasar.org/
- Googleグループで質問する https://groups.google.com/forum/#!forum/dbflute
- Twitterで #DBFlute を入れてつぶやくと、@jflute が捕捉してくれる(はず)
- id:jflute のブログにもたくさんの情報が。
結局かなり長くなってしまった。。。