SlideShare a Scribd company logo
uroboroSQL
〜エンプラで培った秘伝のSQL開発手法をOSS化!〜
Future Architect
Technology Innovation Group
星 賢一
2017/3/10
Who am I ?
星 賢一(Kenichi Hoshi)
フューチャーアーキテクト株式会社
 Technology Innovation Group所属
 技術統括、ディレクター
Activity
 uroboroSQL プロダクトオーナー&テスター&ディベロッ
パー
 社内OSS活動推進、Tech系広報
 技術ブログ責任者&レビューア
Like
 Golang、ES6
 猫
1976年
IBM社によってSQLの元となった
SEQUEL2が誕生
その後、ANSI/ISOによって
規格化、バージョンアップ
SQL87 SQL89
SQL99 SQL:2003 SQL:2008
SQL92
しかし
ベンダー拡張により標準SQL
とは名ばかりの方言の数々
Javaなどの汎用言語とは異なる
集合を扱うためのドメイン固有言語
それが
何かの略じゃないよ!!
JavaとRDBの微妙な関係
インピーダンスミスマッチ
 RDBの特性に合わせたデータモデルと、オブジェクト志向における
現実世界のモデルとのギャップ(マッピング作業)
O/Rマッパー
 インピーダンスミスマッチ問題の解決策として、オブジェクトとRDBのモデ
ルの自動マッピングをするフレームワーク(ライブラリ)
 Javaでは歴史あるフレームワークとしてはHibernateといったOSSや、
Java標準のJPA(EclipseLink、OpenJPA)など、数多のライブラリが存在
O/Rマッパーの種類(1)
QueryBuilder
 FluentAPIによりSQLを自動生成する方式
 タイプセーフなAPIでJavaの世界でデータアクセスが可能なものもある
 動的に条件を変えたりすることが可能でカバレッジもJavaの世界で可能
List<Customer> customers =
db.from(c).
innerJoin(o).on(c.customerId).is(o.customerId).
where(o.total).greaterThan(new BigDecimal("500.00")).
groupBy(c.customerId).select();
List<Customer> employees =
jdbcManager.from(Employee.class)
.innerJoin("department")
.where(new SimpleWhere()
.eq("name", name)
.eq("department.name", deptName)
.getResultList();
S2JDBC
O/Rマッパーの種類(2)
DAO
 DBのテーブル単位でエンティティクラスとDAOクラスを用意(通常は自動生成)
 DAOはGenericDAOとして1クラスのパターンもある
 DAOがCRUDのSQLを自動生成する
EmployeeDao employeeDao = new EmployeeDaoImpl();
Employee employee1 = new Employee()
employee1.name = "HOGE";
employee1.age = 20;
employeeDao.insert(employee1);
Employee employee2 = employeeDao.selectById(1);
employee1.age = 30;
employeeDao.update(employee2);
employeeDao.delete(employee2);
O/Rマッパーの種類(3)
SQL Template
 SQLのテンプレートファイルを別ファイル管理して、パラメータを動的にバインド
 2Way-SQLと呼ばれる通常のSQLとしても実行が可能で、
コメントでIF/ELSE分岐が可能なものもあり
EmployeeDao employeeDao = new EmployeeDaoImpl();
List<Employee> employees = employeeDao.selectByAge(35);
SELECT
/*%expand*/*
FROM
EMPLOYEE
WHERE
AGE < /* age */0
selectByAge.sql
@Select
List<Employee> selectByAge(Integer age);
EmployeeDao.java
2Way-SQL
S2Dao発のSQL実行手法
 元々はSQLプログラマとJavaプログラマの分業が目的(そもそも分業してる?)
 SQLのツールでSQLを実行して思い通りの結果を出力するようになったら、
それに対して、コメントを埋め込んでいくことで生産性が上がるメリットがある
SELECT
*
FROM
EMPLOYEE
WHERE
/*IF salaryMin != null*/
SALARY >= /*salaryMin*/1000
/*END*/
/*IF salaryMax != null*/
AND SALARY <= /*salaryMax*/2000
/*END*/
SELECT
*
FROM
EMPLOYEE
WHERE
SALARY >= ?/*salaryMin*/
salaryMinをパラメータとして渡された
SQLクライアントで、そのままSQLとして
実行される
Javaから呼び出されると、
実行時にIF分岐を評価されて実行される
2Way-SQLの歴史
SeasarプロジェクトのS2Daoが発祥となり、
2Way-SQLを実装する複数のプロダクトが誕生
S2Dao
Mirage-SQL
2006年2003年
2007年
2014年
2017年S2JDBC
2012年
uroboroSQLの紹介 (OSC2017 Tokyo/Spring)
uroboroSQLのはじまり
2006-2007年頃にS2Daoを参考に社内で開発
 もはや当時のことはわからないが、おそらくバグ踏んだときに
迅速に対応したかった・・・?
 その後、社内で似たようなライブラリが開発され、
覇権を争ったが、最終的に生き残り、改善が続けられてきた
 現在、社内では、Webアプリケーションフレームワークや
各種設計開発支援ツールと連携・統合され利用中
社内Webアプリケーションフレームワーク
設計開発支援ツール
なぜOSS化しようと思ったのか?
とある新人や開発パートナーさん
が口を揃えて、こう言います
ググれないから
生産性上がりません
いやいや、開発者向けに
ドキュメント作ってますよ!?
どこに書いてあるか
わかりませんよ
・・・
こうなったら
してやる!!
もうググれないとか言わせないんだからね!!
2016年5月
OSS化始動
業務の合間をぬって、週1,2時間くらい
OSS化にあたって
プロダクト名を決める
テストコードの充実
よくよく見るとイケてない実装のリファクタリング
Java8対応(LocalDate、Optional、Stream)
公開準備
 ロゴ作り
 Githubリポジトリ作成
 GithubPagesでDocument作成
 Maven Centralへのデプロイ
目玉機能もほしい
エンタープライズという荒野を
歩んできた我々にしか出せない
価値があるはず
プロダクトデザイン
コンセプト
SQLの能力を最大限活かしつつ
生産性と品質を高めたい
 Javaを中心に考えてSQLを組み立てるという思想ではなく、
SQLに足りないところをJavaで補うという思想
名は体を表す
 2Way-SQLのメタファとしてuroborosを採用
 PostgreSQLっぽく「uroboroSQL(うろぼろすきゅーる)」に
誰にとってうれしい?どんなシステムに合ってる?
 SQL中心の設計思想が複雑なSQLが必要になるエンタープライズでの
利用に最適なものにしたい
 多人数同時開発を想定し、なるべく共通ライブラリでよろしくやりたい
 事前にコンパイルのできないSQLを高い生産性と品質で作りたい
そして三つのアイディア
が
Idea No.1 - REPL
実装したら即試したい!!いちいちビルドだるい!
SELECT /* _SQL_ID_ */
DEPT.DEPT_NO AS DEPT_NO
, DEPT.DEPT_NAME AS DEPT_NAME
FROM
DEPARTMENT DEPT
WHERE
1 = 1
/*IF SF.isNotEmpty(dept_no)*/
AND DEPT.DEPT_NO = /*dept_no*/1
/*END*/
/*IF SF.isNotEmpty(dept_name)*/
AND DEPT.DEPT_NAME = /*dept_name*/'sample'
/*END*/
department/select_department.sql
DEMO
Idea No.2 - カバレッジ
安心してください。
uroboroSQLなら出せます。
カバレッジレポート出せない?品質保証できるの?
2017/3/10時点ではJenkins Cobertura Pluginに対応
そして、3つ目のアイディアは
Doma、DBFluteを使ってる方も
うれしい機能
uroboroSQLの紹介 (OSC2017 Tokyo/Spring)
SQLは開発者によってインデント、
改行がブレやすいため、汚くなりやすい
SQL
レビューしろとか
辛いんだけど
エンタープライズでは、
1つのSQLで数千行って場合も
だが
あきらめる必要はない
SQL
SQL
Beautiful
uroboroSQL Formatter for Sublime Text 3
S2Dao系記法、
DOMA記法もOK
Installation
https://github.com/future-architect/Sublime-uroboroSQL-formatter
SQLコーディング規約
Future Enterprise Coding Standards for SQL(Oracle)
 uroboroSQL Formatterに完全準拠のコーディング規約
https://future-architect.github.io/coding-standards/
Features
区分値サポート
あらかじめ定義された定数クラス、列挙体が利用可能
SELECT /* _SQL_ID_ */
EMP.EMP_NO AS EMP_NO
, EMP.FIRST_NAME AS FIRST_NAME
, EMP.LAST_NAME AS LAST_NAME
, EMP.BIRTH_DATE AS BIRTH_DATE
, EMP.GENDER AS GENDER
FROM
EMPLOYEE EMP
WHERE
/*IF SF.isNotEmpty(emp_no)*/
AND EMP.EMP_NO = /*emp_no*/1
/*END*/
/*IF female != null and female*/
AND EMP.GENDER = /*#CLS_GENDER_FEMALE*/'M'
/*END*/
シンプル&モダンなAPI
SqlConfig config =
DefaultSqlConfig.getConfig("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", "");
try (SqlAgent agent = config.createAgent()) {
// SELECT
List<Map<String, Object>> depts =
agent.query("dept/select_dept").param("dept_no", 1001).collect();
agent.requiresNew(() -> {
// INSERT
int count = agent.update("dept/insert_dept")
.param("dept_no", 1001)
.param("dept_name", "sales")
.count();
});
}
Java8対応、トランザクションサポートもあり
その他の特徴
エラーハンドリング
 特定のエラーコードでリトライ
SQL実行時のフィルタ
 カラム暗号化
 デバッグログ
バッチ実行
ストアド・プロシージャ実行
クエリキャッシュ
Spring Integration
詳細は展示ブースにて
Install
<dependency>
<groupId>jp.co.future</groupId>
<artifactId>uroborosql</artifactId>
<version>0.1.0</version>
</dependency>
Maven
Gradle
compile group: jp.co.future, name: uroborosql, version: 0.1.0
Documentation
uroboroSQL Document
 https://future-architect.github.io/uroborosql-doc/
uroboroSQL sample application
 https://github.com/future-architect/uroborosql-sample
まとめ
SQLの能力を最大限活かしつつ
生産性と品質の高い開発を!!
開発
展示ブースでお待ちしてます!

More Related Content

uroboroSQLの紹介 (OSC2017 Tokyo/Spring)