uroborosqlの紹介 (osc2017 tokyo/spring)
TRANSCRIPT
uroboroSQL〜エンプラで培った秘伝の SQL 開発手法を OSS 化!〜
Future ArchitectTechnology 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 などの汎用言語とは異なる集合を扱うためのドメイン固有
言語
それが
SQL何かの略じゃないよ!!
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 EMPLOYEEWHERE AGE < /* age */0
selectByAge.sql@SelectList<Employee> selectByAge(Integer age);
EmployeeDao.java
2Way-SQLS2Dao 発の SQL 実行手法
元々は SQL プログラマと Java プログラマの分業が目的(そもそも分業してる?)
SQL のツールで SQL を実行して思い通りの結果を出力するようになったら、 それに対して、コメントを埋め込んでいくことで生産性が上がるメリットがある
SELECT *FROM EMPLOYEEWHERE/*IF salaryMin != null*/ SALARY >= /*salaryMin*/1000/*END*//*IF salaryMax != null*/AND SALARY <= /*salaryMax*/2000/*END*/
SELECT *FROM EMPLOYEEWHERE SALARY >= ?/*salaryMin*/
salaryMin をパラメータとして渡された
SQL クライアントで、そのまま SQL として実行される
Java から呼び出されると、実行時に IF 分岐を評価されて実行される
2Way-SQL の歴史
Seasar プロジェクトの S2Dao が発祥となり、2Way-SQL を実装する複数のプロダクトが誕生
S2Dao
Mirage-SQL
2006 年2003 年
2007 年2014 年
2017 年S2JDBC
2012 年
uroboroSQL のはじまり2006-2007 年頃に S2Dao を参考に社内で開発 もはや当時のことはわからないが、おそらくバグ踏ん
だときに迅速に対応したかった・・・?
その後、社内で似たようなライブラリが開発され、覇権を争ったが、最終的に生き残り、改善が続けられてきた
現在、社内では、 Web アプリケーションフレームワークや各種設計開発支援ツールと連携・統合され利用中
社内 Web アプリケーションフレームワーク
設計開発支援ツール
なぜ OSS 化しようと思ったのか?
とある新人や開発パートナーさん
が口を揃えて、こう言います
ググれないから生産性上がりませ
ん
いやいや、開発者向けにドキュメント作ってます
よ!?
どこに書いてあるか
わかりませんよ
・・・
こうなったら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_NAMEFROM DEPARTMENT DEPTWHERE 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 を使ってる方も
うれしい機能
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 GENDERFROM EMPLOYEE EMPWHERE/*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
Gradlecompile group: jp.co.future, name: uroborosql, version: 0.1.0
DocumentationuroboroSQL Document https://future-architect.github.io/uroborosql-doc/
uroboroSQL sample application https://github.com/future-architect/uroborosql-sample
まとめ
SQL の能力を最大限活かしつつ生産性と品質の高い開発を!!
開発
展示ブースでお待ちしてます!