SlideShare a Scribd company logo
1 of 52
Download to read offline
Doma 
SQLテンプレートのしくみ 
by @nakamura_to
@nakamura_to
Domaとは ? 
3
DBアクセスライブラリ 
• コンパイル時のコード生成 & チェック 
• 2 Way SQL対応テンプレート 
• Java 8対応 
• 依存ライブラリなし
デモ 
5
DAOインタフェース 
example/EmployeeDao.java 
@Dao(config = AppConfig.class) 
public interface EmployeeDao { 
@Select 
Employee selectById(Integer id); 
}
SQLファイル 
META-INF/example/EmployeeDao/selectById.sql 
select 
* 
from 
employee 
where 
id = /* id */0
コンパイル 
• SQLファイルの存在チェック 
• バインド変数のマッピングチェック 
• DAO実装クラスの生成
実行 
EmployeeDao employeeDao = new EmployeeDaoImpl(); 
Employee result = employeeDao.selectById(1); 
select 
* 
from 
employee 
where 
id = ?
Domaの系譜 
10
S2Dao 
(2004) 
DBFlute 
(2006) 
JPA 
(2006) 
S2JDBC 
(2007) 
Doma 
(2009) 
Hibernate 2 
(2003)
S2Daoから継承したこと 
2 Way SQL 
実装のいらないDAO
S2Daoから継承しなかったこと 
命名規約 
SELECT文の自動生成 
2 Way SQLの実装 
/*BEGIN*/WHERE 
/*IF job != null*/job = /*job*/'CLERK'/*END*/ 
/*IF deptno != null*/AND deptno = /*deptno*/20/*END*/ 
/*END*/
DBFluteから継承したこと 
DateFromTo: 時刻の切捨て/切上げ
DBFluteから継承しなかったこと 
ReplaceSchemaなどの周辺ツール
S2JDBCから継承したこと 
RDBMSの挙動の違いを抽象化する方法 
自動生成系SQLの組み立て方
S2JDBCから継承しなかったもの 
ライブラリへの依存 
Criteria(流れるインタフェース)
JPAから継承したもの 
アノテーション
JPAから継承しなかったもの 
永続コンテキスト 
リレーションシップ 
遅延ローディング 
専用の問い合わせ言語(JPQL)
なぜ 
SQLテンプレート 
を使うべきか? 
20
可読性を高くする 
• StringBuilderと条件分岐でクエリを組み立て 
るのは煩雑 
StringBuilder buf = new StringBuilder(); 
buf.append("select * from emp"); 
if (id != null) { 
buf.append(" where id = ?"); 
} 
String sql = buf.toString(); 
select * from emp where 
/*%if e.id != null*/ 
id = /* e.id */0 
/*%end */ 
✖
検証しやすくする 
• StringBuilderで組み立てるとSQLの構文が正 
しいか検証するのが手間 
StringBuilder buf = new StringBuilder(); 
buf.append("select * from emp"); 
if (id != null) { 
buf.append("where id = ?"); 
} 
String sql = buf.toString(); 
select * from emp where 
/*%if e.id != null*/ 
id = /* e.id */0 
/*%end */ 
✖
SQLインジェクションを防ぐ 
• 検索条件はPreparedStatementの?にバインド 
StringBuilder buf = new StringBuilder(); 
buf.append("select * from emp"); 
if (id != null) { 
buf.append(" where id = " + id); 
} 
String sql = buf.toString(); 
select * from employee where 
name = /* e.name */'hoge' 
select * from employee where 
name = ? 
✖
メンタルモデルに合わせる 
• SQLは専用のエディタでDBにつなぎ、小さく 
ちょっとずつ組み立てたい 
select * from emp 
select * from emp where salary > 1000 
select * from emp where salary > 1000 order by name 
select name, salary from emp where salary > 1000 order by name 
select name, salary from emp where salary > /*e.salary*/0 order by name
Domaの 
SQLテンプレートの 
何が良いのか?
存在しないプロパティアクセ 
スはコンパイルエラー 
@Select 
List<Employee> selectByExample(Employee e); 
select * from emp where salary > /*e.hoge*/0
条件分岐の間違いはコンパイ 
ルエラー 
select * from emp where 
/*%if e.id != null */ 
id = /* id */0
広いスコープの条件分岐はコ 
ンパイルエラー 
/*%if e.name == null */ 
select count(*) from emp 
/*%else */ 
select * from emp where name = /* e.name */'hoge' 
/*%end * 
select * from emp where 
/*%if e.name == null */ 
name = /* e.name */'hoge' 
/*%else */ 
and 
name is null 
/*%end * 
✖
SQL構文木の構築と走査 
29
DAOインタフェース 
@Dao(config = AppConfig.class) 
public interface EmpDao { 
@Select 
Emp select(Emp e); 
@Select 
List<Emp> selectList(Emp e); 
}
SQLテンプレートselect * from emp where 
パース 
構文木 
走査 
/*%if e.id != null*/ 
id = /* e.id */0 
/*%end */ 
マッピングや 
式言語の文法 
チェック 
• eはメソッドパラメータに存在する? 
• id はEmpに存在する? 
• if と end は対応している? 
コンパイル時
SQLテンプレートselect * from emp where 
パース 
構文木 
実行時 
走査 
/*%if e.id != null*/ 
id = /* e.id */0 
/*%end */ 
select * from emp where 
id = ? 
SQLの生成or 
select * from emp
SQLテンプレートselect * from emp where 
パース 
構文木 
実行時(ページング) 
変換 
走査 
salary > /* e.salary */0 
ページング用 
構文木 
SQLの生成 
select * from emp where 
salary > ? 
offset 10 limit 100
パース 
構文木 
実行時(悲観的ロック) 
SQLテンプレートselect * from emp where 
id = /* e.id */0 
変換 
悲観的ロック用 
構文木 
SQLの生成 
select * from emp where 
id = ? 
for update 
走査
なぜ構文木を構築する? 
SQLを変換したい 
コンパイル時と実行時で異なる処理をしたい 
が、できるだけ共通化したい
RDBMSのSQL方言対応 
パース時はRDBMSごとのSQL方言を考慮せ 
ず、共通的なノードのみ押さえる 
変換(ページング、悲観的ロック)のみを方 
言ごとに実行できるようにする 
新しい方言への対応は容易な作り
構築と変換 
データ構造
SQLファイル 
select * from emp where 
/*%if e.id != null*/ 
id = /* e.id */0 
/*%end */
Anonymous 
SelectStatement 
SelectClause FromClause WhereClause 
Word Space Word Space 
from emp 
Word Space Other Space 
select * 
Word Space IfBlock 
where 
/*%if e.id != null */ If End /*%end */ 
Space Word Space Other Space BindVariable Space 
Word 
0 
id != /* e.id */ 
木の構築
Fragment 
offset 10 
Fragment 
limit 100 
If 
Anonymous 
SelectStatement 
SelectClause WhereClause 
IfBlock 
End 
Word Space Other 
FromClause 
Space Word Space Word Space Space 
select * from emp 
Space Word Space Other Space BindVariable Space 
id != /* e.id */ 
/*%end */ 
Word 
0 
/*%if e.id != null */ 
Word 
where 
木の変換(ページング) 
OrderByClause
If 
Anonymous 
SelectStatement 
SelectClause WhereClause 
IfBlock 
End 
Word Space Other 
FromClause 
Space Word Space Word Space Space 
select * from emp 
Space Word Space Other Space BindVariable Space 
id != /* e.id */ 
/*%end */ 
Word 
0 
/*%if e.id != null */ 
Word 
where 
木の変換(悲観的ロック) 
ForUpdateClause 
Word 
for update
スペースを保つ 
スタイルの維持 
行や列数の報告
式言語の構築と走査 
43
Anonymous 
SelectStatement 
SelectClause FromClause WhereClause 
Word Space Word Space 
from emp 
Word Space Other Space 
select * 
Word Space IfBlock 
where 
/*%if e.id != null */ If End /*%end */ 
Space Word Space Other Space BindVariable Space 
Word 
0 
id != /* e.id */
e.id != null 
NeOperator 
木の構築 
FieldOperator Literal 
id 
Variable 
null 
!= 
e 
FieldOperator 
id 
Variable 
e 
e.id 
• コンパイル時にも実行時にも走査
まとめ 
46
まとめ 
• DomaのSQLテンプレートはコンパイル時 
チェックが可能 
• SQLの構文木と式言語の構文木を構築して 
チェック 
• 新しいRDMBSへの対応は容易
ハックして何か新しい機能を!
参考情報 
49
GitHub Repository 
https://github.com/domaframework/doma
Doma 2 
Java 8 時代のDBアクセス 
https://nakamura-to.github.io/presentation-doma2- 
with-java8/
Thank you

More Related Content

What's hot

O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション土岐 孝平
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門増田 亨
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き土岐 孝平
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装infinite_loop
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門Takuya Kitamura
 
SpringBootにおけるテンプレートエンジンの活用
SpringBootにおけるテンプレートエンジンの活用SpringBootにおけるテンプレートエンジンの活用
SpringBootにおけるテンプレートエンジンの活用iPride Co., Ltd.
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)Koichiro Matsuoka
 
Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門Satoshi Kubo
 
ミクシィ 21卒向け Android研修
ミクシィ 21卒向け Android研修ミクシィ 21卒向け Android研修
ミクシィ 21卒向け Android研修akkuma
 
SPAのルーティングの話
SPAのルーティングの話SPAのルーティングの話
SPAのルーティングの話ushiboy
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発慎一 古賀
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring増田 亨
 
「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainerYuta Matsumura
 
Clean Architectureで設計してRxJSを使った話
Clean Architectureで設計してRxJSを使った話Clean Architectureで設計してRxJSを使った話
Clean Architectureで設計してRxJSを使った話_kondei
 
Django の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsDjango の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsMasashi Shibata
 

What's hot (20)

O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション怖くないSpring Bootのオートコンフィグレーション
怖くないSpring Bootのオートコンフィグレーション
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き入社1年目のプログラミング初心者がSpringを学ぶための手引き
入社1年目のプログラミング初心者がSpringを学ぶための手引き
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門
 
SpringBootにおけるテンプレートエンジンの活用
SpringBootにおけるテンプレートエンジンの活用SpringBootにおけるテンプレートエンジンの活用
SpringBootにおけるテンプレートエンジンの活用
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
PostgreSQLの行レベルセキュリティと SpringAOPでマルチテナントの ユーザー間情報漏洩を防止する (JJUG CCC 2021 Spring)
 
Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門Junitを使ったjavaのテスト入門
Junitを使ったjavaのテスト入門
 
ミクシィ 21卒向け Android研修
ミクシィ 21卒向け Android研修ミクシィ 21卒向け Android研修
ミクシィ 21卒向け Android研修
 
SPAのルーティングの話
SPAのルーティングの話SPAのルーティングの話
SPAのルーティングの話
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
 
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Springドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
 
「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer「自分のとこでは動くけど…」を無くす devcontainer
「自分のとこでは動くけど…」を無くす devcontainer
 
Clean Architectureで設計してRxJSを使った話
Clean Architectureで設計してRxJSを使った話Clean Architectureで設計してRxJSを使った話
Clean Architectureで設計してRxJSを使った話
 
Django の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication PatternsDjango の認証処理実装パターン / Django Authentication Patterns
Django の認証処理実装パターン / Django Authentication Patterns
 

Similar to Doma SQLテンプレートのしくみ

20091030cakephphandson 02
20091030cakephphandson 0220091030cakephphandson 02
20091030cakephphandson 02Yusuke Ando
 
「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみようKentaro Matsui
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Nextdynamis
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜ericsagnes
 
S2dao Seminar in tripodworks
S2dao Seminar in tripodworksS2dao Seminar in tripodworks
S2dao Seminar in tripodworkstripodworks
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説do_aki
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方Soudai Sone
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようAkira Shimosako
 
よろしい、ならばMicro-ORMだ
よろしい、ならばMicro-ORMだよろしい、ならばMicro-ORMだ
よろしい、ならばMicro-ORMだNarami Kiyokura
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Yu Nobuoka
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)Masanori Machii
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造Taku Miyakawa
 
final int をFINAL しやがれ!
final int をFINAL しやがれ!final int をFINAL しやがれ!
final int をFINAL しやがれ!Keiichi Nagaoka
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogrammingMasanori Kado
 

Similar to Doma SQLテンプレートのしくみ (20)

20091030cakephphandson 02
20091030cakephphandson 0220091030cakephphandson 02
20091030cakephphandson 02
 
「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう「Html sql」で図書館hpにアクセスしてみよう
「Html sql」で図書館hpにアクセスしてみよう
 
Kanazawa.js.Next
Kanazawa.js.NextKanazawa.js.Next
Kanazawa.js.Next
 
01 php7
01   php701   php7
01 php7
 
DeclarativeSql
DeclarativeSqlDeclarativeSql
DeclarativeSql
 
eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜eZ Publish勉強会9月〜テンプレート言語〜
eZ Publish勉強会9月〜テンプレート言語〜
 
S2dao Seminar in tripodworks
S2dao Seminar in tripodworksS2dao Seminar in tripodworks
S2dao Seminar in tripodworks
 
Perl勉強会#2資料
Perl勉強会#2資料Perl勉強会#2資料
Perl勉強会#2資料
 
PHP AST 徹底解説
PHP AST 徹底解説PHP AST 徹底解説
PHP AST 徹底解説
 
知って得する標準関数の使い方
知って得する標準関数の使い方知って得する標準関数の使い方
知って得する標準関数の使い方
 
Reading Anorm 2.0
Reading Anorm 2.0Reading Anorm 2.0
Reading Anorm 2.0
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみよう
 
よろしい、ならばMicro-ORMだ
よろしい、ならばMicro-ORMだよろしい、ならばMicro-ORMだ
よろしい、ならばMicro-ORMだ
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成
 
第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)第2回品川Redmine勉強会(日本語全文検索)
第2回品川Redmine勉強会(日本語全文検索)
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造
 
final int をFINAL しやがれ!
final int をFINAL しやがれ!final int をFINAL しやがれ!
final int をFINAL しやがれ!
 
Project lambda
Project lambdaProject lambda
Project lambda
 
URLで遊ぼう
URLで遊ぼうURLで遊ぼう
URLで遊ぼう
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 

Doma SQLテンプレートのしくみ