ハンズオンセクション 7

概要

さて、ハンズオンの続きです。

"Behaviorで登録 (+ 自動採番、共通カラム)" を学んでいきましょう。

事前準備

src/main/java 配下に org.docksidestage.handson.logic.HandsOn07Logic クラスを作成してください。この時点では空っぽで構いません。また、ERDを開いておくと良いでしょう。

【事務連絡】org.dbflute.handson から、org.docksidestage.handson に変わりました。 org.dbfluteで開始した人は、そのまま org.dbflute で続けてOKです。もし、移行するなら log4j.properties と basicInfoMap.dfprop の該当箇所を修正してください。

データの登録

今までひたすら検索をやってきましたが、ここでようやく登録です。 Behavior から Entity をもらうのではなく、Entity を渡してみましょう。

以下のロジックを作成してみましょう。

ロジックのメソッド (HandsOn07Logic)
Member insertMyselfMember()
  • 自分自身の会員を登録
  • 正式会員で登録
  • 現在日時を取得する Logic を作成して、正式会員日時を入れる
現在日時取得ロジック (CurrentTimeLogic)
  • currentDate() : LocalDate で現在日時を戻す
  • currentDateTime() : LocalDateTime で現在日時を戻す
対応テストメソッド
test_insertMyselfMember_会員が登録されていること()
  • 登録後の Entity から主キーの値を使って検索すること
  • とりあえず、会員名称と生年月日だけアサート

現在日時は、Javaから取らない

現在日時は差し替えたい

現在日時は、各機能が直接 Java から取らないのが流儀です。

アプリには、月初、月末、年末など時間限定でないと動かないプログラムもよくあります。 それらをテストするのにはどうしたらいいでしょう? PCのシステム日付を変える方法もありますが、ファイル更新日時などがひっくり返って戻したときに予期せぬ挙動をしたり、ライセンス周りの挙動がおかしくなったりと、 あまりやりたいことではありません。

統一した現在日時インターフェース

そこでよく利用されるのが、アプリで "現在日時を提供するインターフェース" を用意して、その実装をちょっとだけ差し替えることで自由に "アプリ内の現在日時" を変更する方法です。 実際には、実装の差し替えというよりかは設定ファイルで変更できるするようにします。

そのためには、それぞれが直接 Java から現在日時を取ってはいけないのです。

新しい開発プロジェクトに入って現在日時を取得する場面に遭遇したら、まずは聞いてみましょう。 現在日時を取得する統一的なインターフェースがありますでしょうか?

ということでロジックを

ということで、このハンズオンでは、現在日時を取得するロジックを作ってもらいました。 もし、本当に現在日時を差し替えてテストしたいとなれば、このロジックを切り替えたり、ロジックの中でうまく fake するような処理を入れたりするとよいでしょう。

共通カラムの設定

先ほどのロジックで、登録日時や更新日時はどうしたでしょうか?

...個別個別に設定しないと登録できなかったかと思います。 ですが、DBFlute には、データ登録・更新時に発生する共通カラムへの定型的な設定処理、これを自動で行う機能があります。

dfpropに設定して自動生成

UnitTest環境では、UTFluteの中ですでに AccessContext は設定されているので、このエクササイズでやるのではdfpropでの共通カラムの設定と自動生成だけとなります。

commonColumnMap.dfprop に、以下の内容を設定して再自動生成(DocとGenerate)してください。

※Java6 (DBFlute-1.0.x) なら getAccessLocalDateTimeOnThread() は getAccessTimestampOnThread() に変更

e.g. DBFluteプロパティでの共通カラムの設定 @commonColumnMap.dfprop
...
    ; commonColumnMap = map:{
        ; REGISTER_DATETIME=TIMESTAMP ; REGISTER_USER=VARCHAR
        ; UPDATE_DATETIME=TIMESTAMP   ; UPDATE_USER=VARCHAR
    }
    ; beforeInsertMap = map:{
        ; REGISTER_DATETIME = $$AccessContext$$.getAccessLocalDateTimeOnThread()
        ; REGISTER_USER     = $$AccessContext$$.getAccessUserOnThread()
        ; UPDATE_DATETIME   = entity.getRegisterDatetime()
        ; UPDATE_USER       = entity.getRegisterUser()
    }
    ; beforeUpdateMap = map:{
        ; UPDATE_DATETIME   = $$AccessContext$$.getAccessLocalDateTimeOnThread()
        ; UPDATE_USER       = $$AccessContext$$.getAccessUserOnThread()
    }
...

SchemaHTML確認、そして、テスト再実行

まずは、SchemaHTML (schema-maihamadb.html) を確認してみましょう。共通カラム部分のデザインがほんの少し変わったはずです。

そして、先ほどのロジックから共通カラムの設定をコメントアウトしてテストを再実行してみてください。 ログで共通カラムの登録された値を確認してみてください。

バージョンNOも設定不要

バージョンNOに関しては次のセッションで詳しく説明がありますが、 とりあえず登録時にバージョンNOは明示的に設定する必要はないということだけ覚えておいてください。

さらに登録してみましょう

では、エクササイズです。さらに登録してみましょう。

※ExampleDB の ERD と、この時点で利用している実際のテーブル構造(主にカラム名やカラムの構造)では、明らかにおかしいカラム名 があったりなど、一部食い違っているのでご注意ください。

ロジックのメソッド
Member insertYourselfMember()
  • 誰かを正式会員として登録
  • 業務的に必須の関連テーブルも登録
テストメソッド
test_insertYourselfMember_会員が登録されていること()
  • 登録されていることを代表的なカラムを利用してアサート
  • 関連テーブルの登録もアサート
  • 登録していない関連テーブルが登録されていないこともアサート

次のセクション

さて、次のセクションへ