Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
DBFlute bridges between DB and App
Search
jflute
October 17, 2015
Programming
1
3k
DBFlute bridges between DB and App
at JPOUG> SET EVENTS 20151017
jflute
October 17, 2015
Tweet
Share
More Decks by jflute
See All by jflute
How Unext took in Eclipse Collections in FW
jflute
0
720
How to fork Seasar (LastaFlute)
jflute
0
190
LastaFlute First Impact
jflute
7
7.3k
Other Decks in Programming
See All in Programming
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
300
関数型まつりレポート for JuliaTokai #22
antimon2
0
160
ニーリーにおけるプロダクトエンジニア
nealle
0
590
Goで作る、開発・CI環境
sin392
0
140
アンドパッドの Go 勉強会「 gopher 会」とその内容の紹介
andpad
0
270
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
560
Cursor AI Agentと伴走する アプリケーションの高速リプレイス
daisuketakeda
1
130
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
110
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
4
1k
PicoRuby on Rails
makicamel
2
110
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
510
Deep Dive into ~/.claude/projects
hiragram
9
1.6k
Featured
See All Featured
For a Future-Friendly Web
brad_frost
179
9.8k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
A better future with KSS
kneath
239
17k
Raft: Consensus for Rubyists
vanstee
140
7k
Git: the NoSQL Database
bkeepers
PRO
430
65k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
930
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
How to Think Like a Performance Engineer
csswizardry
24
1.7k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.3k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
281
13k
The Straight Up "How To Draw Better" Workshop
denniskardys
234
140k
Building Applications with DynamoDB
mza
95
6.5k
Transcript
DBをリファクタリングしよう、 DBとアプリの架け橋 DBFlute by 久保雅彦(jflute)
わたしはだれ? 久保 雅彦 (jflute) オープンソースプログラマー DBFluteの作者 jfluteの日記(http://d.hatena.ne.jp/jflute/) Twitter: @jflute / facebook:
dbflute 2 自己紹介
住んでるところ Java, JDBC, フレームワーク, DB設計, プログラマー教育 オープンソース 3 自己紹介
DBFluteとは? O/Rマッパー DB管理支援ツール 4 DBFluteとは?
DBFluteの特徴は? DB変更に強い 5 DBFluteとは?
DBFluteのターゲット BtoCなどのサービス開発 (事業会社) リーン・スタートアップ インクリメンタル開発 DB設計と実装の同時開発 ※ビジネスのための泥臭いツール 6 DBFluteとは?
… ふーん 7 DBFluteとは?
DBFluteは変えたい DBサイドとアプリサイドの 8 DBFluteとは? ギャップ
ギャップって? DBサイド:DB設計、インフラ アプリサイド:アプリ開発 互いが互いに責め合う(T∀T) 9 DBFluteとは?
DBサイドとアプリサイドの ギャップ その1 DB設計の意図が アプリ側に伝わらない 10 ギャップその1
アプリあるある どこにIndex貼ってあるのかわからない NotNull制約の外れてる理由がわからない どことどこをjoinすればいいのか… この区分値、何が入るの? 11 ギャップその1:DB設計の意図が伝わらない
アプリあるある 40.テーブル定義書フォルダに.xls発見、開く ウィルスチェック、開くまで待つ待つ 大量のシートで途方にくれる “エクセル シート移動 ショートカット”で検索 見たいテーブル見つけたー、…先輩通りすがる 「それ古いから見ない方がいいよ」 12
ギャップその1:DB設計の意図が伝わらない
というのから 卒業 13 ギャップその1:DB設計の意図が伝わらない
DBFluteはDBを伝える! テーブル定義を自動生成 (SchemaHTML) メンテナンス不要(DBコメント重視) 気楽に開けるHTML形式 DB定義をJavaDocコメントに DBコメントをJavaDocコメントに xlsは精神的距離が遠いが、JavaDocは近い 14
ギャップその1:DB設計の意図が伝わらない
SchemaHTML (テーブル一覧) 15 ギャップその1:DB設計の意図が伝わらない
SchemaHTML (テーブル詳細) 16 ギャップその1:DB設計の意図が伝わらない
DBサイドとアプリサイドの ギャップ その2 アプリ側の都合に関係なく DB変更される 17 ギャップその2
アプリあるある 気付いたらDB変わってて落ちてる 影響範囲ありすぎでデグレまくる ローカル開発用DBがめっちゃ古い 18 ギャップその2:DB変更される
DBFluteはDB変更につおい! タイプセーフAPI (ConditionBean) で DB変更の影響範囲検知 2WaySQLの外出しSQLを 一括実行で検知 最新DB構造の横展開を自動化 (ReplaceSchema) バッチ一発で、サクッとDB作り直し
テストデータの一元管理 19 ギャップその2:DB変更される
ConditionBean 20 FKラインを辿る旅 DBが綺麗であればあるほど 実装しやすくなる というインセンティブ ギャップその2:DB変更される
一括テスト実行できる 2WaySQL (OutsideSql) 21 ギャップその2:DB変更される
DBAの人も DB変更の影響規模を 探りやすい ローカルで試しに変えてみて バッチを叩けばOK 22 ギャップその2:DB変更される
DBサイドとアプリサイドの ギャップ その3 というか… DB変更の内容が アプリ側に伝わらない 23 ギャップその3
アプリあるある 何が変わったのかがわからない 直すべきところわからず放置 というかDBAも細かく伝えるの面倒 24 ギャップその3:DB変更が伝わらない
DBFluteはDB変更を伝える! HistoryHTMLで 履歴ドキュメントを自動生成 (自然と作られていくところがポイント) もちろん、 JavaDocコメントや SchemaHTMLも大活躍 25 ギャップその3:DB変更が伝わらない
HistoryHTML 26 ギャップその3:DB変更が伝わらない
プロシージャだって 27 ギャップその3:DB変更が伝わらない
DBサイドとアプリサイドの ギャップ その4 アプリが ぐるぐる回す (ぶーんぶーんばばーん!) 28 ギャップその4
チューニングあるある 一回のリクエストで300回のSQL 一個一個は速いので、頼まれても DB側の調整ではどうにもならない (jflute経験済み) 夜間バッチだと…ひぃぃぃー 29 ギャップその4:アプリがぐるぐる回す
フレームワークあるある getMemberStatus() された時に検索 List<Member> memberList = …(最初の検索) for (Member member
: memberList) { member.getMemberStatus() // ひぃぃぃー } getされた時に関連テーブルのデータを検索 いわゆる LazyLoad 機能 30 ギャップその4:アプリがぐるぐる回す
DBFluteは明文主義 データ取得したい関連テーブル明示 getメソッドでLazyLoadしない SQLの発行回数を数えるための 拡張ポイント (CallbackContext) 31 ギャップその4:アプリがぐるぐる回す
SQLの発行回数をログに …(σόοάϩάͷத) [request] lastaflute.dbflute.SQL_COUNT= {total=2, selectCB=2, entityUpdate=0 , queryUpdate=0, outsideSql=0,
procedure=0} … ※DBFluteͱ࿈ܞͨ͠WebϑϨʔϜϫʔΫ ʮLastaFluteʯʹͯ 32 ギャップその4:アプリがぐるぐる回す
発行しすぎ警告ログ …(ܯࠂϩάͷத) *Too many SQL executions: {total=81, selectCB=3, entityUpdate=78, queryUpdate=0,
outsideSql=0, procedure=0} ɹin ProductListAction.search() … ※DBFluteͱ࿈ܞͨ͠WebϑϨʔϜϫʔΫ ʮLastaFluteʯʹͯ 33 ギャップその4:アプリがぐるぐる回す
こういう視点も DBの問題はDBだけでは 解決できない ↓ Webフレームワーク との連携も大切 34 ギャップその4:アプリがぐるぐる回す
ちなみに SQLをべたっと書けばぐるぐるが消える というのはまちがい ↓↓↓ プログラム上でSQLを組み立てづらい環 境だからこそ面倒になってぐるぐるする ↓↓↓ LazyLoadしなくて、 SQLを組み立てやすいツール の方が防げきやすい
(無論100%防げるわけではないが比較的) 35 ギャップその4:アプリがぐるぐる回す
DBサイドとアプリサイドの ギャップ その5 本番と結合と開発で、 スキーマ構造が違う! 36 ギャップその5
アプリ, DBAあるある 落ちた ↓ 調べる ↓ 本番DB違う 37 Alter書いた ↓
Index書き忘れた ↓ 実行し忘れた ギャップその5:本番とスキーマちっがーう
スタートアップあるある まず、ズレる (毎週のようにDB変更しますから…) 38 ギャップその5:本番とスキーマちっがーう
DBFluteは差分大好き HistoryHTMLでDB変更の歴史 AlterCheckで Alter文の整合性チェック SchemaSyncCheckで 二つのDBの差分チェック DB差分御三家を呼ぶ 39 ギャップその5:本番とスキーマちっがーう
AlterCheckの方程式 前のDB + 差分DDL = 最新のフルDDL 40 ギャップその5:本番とスキーマちっがーう
AlterCheckの流れ 1. 前のDB (フルDDL) を保存 by DBFlute 2. 普通にDB変更 by
ERD 3. Alter文を書く by 人類 4. フルDDLを吐き出して… by ERD 5. 方程式と合わせる by DBFlute 41 ギャップその5:本番とスキーマちっがーう
AlterCheckの結果 ダメ だったら… 差分がなくなるまで差し戻し 42 ギャップその5:本番とスキーマちっがーう
DBサイドとアプリサイドの ギャップ その6 アプリ屋さんよぅ… パフォーマンス考慮お願い 43 ギャップその6
DBFluteはSQLを大切に1 発行されるSQLは徹底フォーマット (プログラマーがすぐにログ確認。実行はバインド変数) 44 ギャップその6:パフォーマンス考慮たのむよー
DBFluteはSQLを大切に2 発行されたSQLの実行時間をログに (プログラマーに普段から意識してもらう) 45 ギャップその6:パフォーマンス考慮たのむよー ※結果の件数もね
DBFluteはSQLを大切に3 どこから呼ばれたSQL?をログに (プログラマーをSQLに振り向かせる) 46 ギャップその6:パフォーマンス考慮たのむよー LastaFluteと連携でSQLにアプリクラス埋め込みも (DB側でSQLを抽出しても、どこのSQLかすぐにわかる)
DBFluteはSQLを大切に4 EntityのSetter呼び出し情報でupdate文を構築 (無駄な事前検索や問答無用全カラム更新しない) Member mb = new Member(); mb.setMemberId(3); mb.setMemberName(“jflute”);
memberBhv.update(mb); ↓↓↓ update MEMBER set MEMBER_NAME = ‘jflute’ where MEMBER_ID = 3 47 ギャップその6:パフォーマンス考慮たのむよー
DBをリファクタリングするために RDBを隠蔽するのではなく、 RDBを強く意識させる O/Rマッパー DBFlute 48 まとめ
DBサイドとアプリサイド どっちもWinWinになってこそ、 お客様も最高のシステムに 出会えるはず 49 まとめ
架け橋 そのためのツール、 選んでみませんか? 50 まとめ