Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
次世代 Dao フレームワーク  Doma (ドマ) 第 56 回 JavaEE 勉強会 中村年宏  ( http://d.hatena.ne.jp/taedium/)
Doma (ドマ)とは <ul><li>D omain  O riented  MA pping Framework </li></ul><ul><ul><li>Domain (ドメイン)  =  値の定義域 </li></ul></ul><u...
Doma のコンセプト <ul><li>Domain(ドメイン)中心 </li></ul><ul><li>宣言的プログラミング </li></ul><ul><li>コンパイル時のコード自動生成 </li></ul>
Domain (ドメイン)中心  -  ドメインとは? @Entity public   class  Employee { @Id private  Integer  id; private  String  name; private  S...
Domain (ドメイン)中心 –  Domain インタフェースとその実装 public   interface  Domain<V, D  extends  Domain<V, D>> { V get(); void  set(V valu...
Domain (ドメイン)中心 – なぜ? <ul><li>意図を明確に表せる </li></ul><ul><li>値に特化したメソッドを持てる </li></ul><ul><ul><li>PhoneNumber に国番号を扱うメソッドをもつと...
宣言的プログラミング –  Entity の場合 @Entity public   class  Employee { @Id private  Integer id; private  String name; private  String...
宣言的プログラミング –  Dao の場合 @Dao(config = AppConfig.class) public  interface EmployeeDao { @Select(fetchSize = 50) Employee sele...
コンパイル時のコード生成 <ul><li>Pluggable Annotation Processing API を利用 </li></ul><ul><ul><li>Java6 から導入された機能 </li></ul></ul><ul><ul>...
コンパイル時のコード生成 – 例 @Override public  org.seasar.doma.it.entity.Employee selectById(org.seasar.doma.it.domain.Identity employ...
Doma の機能 – 概要 <ul><li>複数 RDBMS 対応 </li></ul><ul><ul><li>今は HSQLDB 、 Oracle 、 PostgerSQL 、 MySQL </li></ul></ul><ul><li>2Wa...
Doma の機能 –  SQL 関連 <ul><li>検索系 </li></ul><ul><ul><li>Dao のメソッドに @Select をつける </li></ul></ul><ul><ul><li>自動生成しない。 SQL ファイルと...
Doma の機能 –  SQL ファイル関連 <ul><li>ファイルは Dao ごとに管理 </li></ul><ul><li>SQL コメントのルールは S2Dao に似た感じ </li></ul>select * from employe...
Doma の機能 –  apt 関連 <ul><li>SQLファイルの存在チェック </li></ul><ul><ul><li>SQLファイルが必要なDaoメソッドに対応するファイルが存在しない場合はエラーメッセージを表示。 </li></ul...
デモ Doma は、 Java6 で動作します。 Java5 以前はサポートしてません。 IDE は Eclipse3.5 で動作することを確認しています。( 3.4 だと動かないところあるかも。) apt をサポートしていれば Eclipse...
まとめ –  Doma の良いところ <ul><li>Domain の利用で意図が明確かつ型安全。 </li></ul><ul><li>明示的な設定。 </li></ul><ul><ul><li>命名規約はない。ルールから外れたら apt で通...
Upcoming SlideShare
Loading in …5
×

次世代DaoフレームワークDoma

6,876 views

Published on

Published in: Technology
  • Be the first to comment

次世代DaoフレームワークDoma

  1. 1. 次世代 Dao フレームワーク Doma (ドマ) 第 56 回 JavaEE 勉強会 中村年宏 ( http://d.hatena.ne.jp/taedium/)
  2. 2. Doma (ドマ)とは <ul><li>D omain O riented MA pping Framework </li></ul><ul><ul><li>Domain (ドメイン) = 値の定義域 </li></ul></ul><ul><ul><li>Doma では String や Integer の定義域をより狭めたものを Domain (ドメイン)と呼ぶ </li></ul></ul><ul><li>名前だけだと汎用的だけど、カテゴリとしては Dao フレームワーク( O/R マッパー) </li></ul><ul><li>Java6 ( JDBC4.0 )対応 </li></ul><ul><li>他のライブラリに依存していない </li></ul><ul><li>Seasar プロジェクトの Sandbox で開発中 </li></ul><ul><ul><li>SVN リポジトリ </li></ul></ul><ul><ul><ul><li>https://www.seasar.org/svn/sandbox/doma/ </li></ul></ul></ul><ul><ul><li>SNAPSHOT </li></ul></ul><ul><ul><ul><li>http://maven.seasar.org/maven2-snapshot/org/seasar/doma/doma/0.9.0-SNAPSHOT/ </li></ul></ul></ul><ul><ul><li>ドキュメント </li></ul></ul><ul><ul><ul><li>なし。。。 </li></ul></ul></ul>
  3. 3. Doma のコンセプト <ul><li>Domain(ドメイン)中心 </li></ul><ul><li>宣言的プログラミング </li></ul><ul><li>コンパイル時のコード自動生成 </li></ul>
  4. 4. Domain (ドメイン)中心 - ドメインとは? @Entity public class Employee { @Id private Integer id; private String name; private String phoneNumber; // … } @Entity public interface Employee { @Id Identity id(); Name name(); PhoneNumber phoneNumber(); // … } よくある一般的なEntity(JPAとか) Doma の Entity カラムの概念ごとにアプリ固有のクラスを作成(あらかじめ用意されたクラスもあり)。 Domain というインタフェースを実装 。
  5. 5. Domain (ドメイン)中心 – Domain インタフェースとその実装 public interface Domain<V, D extends Domain<V, D>> { V get(); void set(V value); void set(D other); boolean isNull(); boolean isNotNull(); boolean isChanged(); void setChanged( boolean changed); Class<V> getValueClass(); <R, P, TH extends Throwable> R accept(DomainVisitor<R, P, TH> visitor, P p) throws TH; } public class PhoneNumber extends AbstractStringDomain<PhoneNumber> { private static final long serialVersionUID = 1L; public PhoneNumber() { } public PhoneNumber(String value) { super (value); } } Domainインタフェース 実装例 String とか Integer のラッパーみたいなもの。 ここでは DB の型とのマッピング情報もたない。 Visitor パターンで RDBMS ごとにマッピング。 抽象クラスが用意されているので通常は継承するだけ。 直接 Domain インタフェースを実装することも可。 好きなメソッドを定義できる。
  6. 6. Domain (ドメイン)中心 – なぜ? <ul><li>意図を明確に表せる </li></ul><ul><li>値に特化したメソッドを持てる </li></ul><ul><ul><li>PhoneNumber に国番号を扱うメソッドをもつとか </li></ul></ul><ul><ul><li>ひとつのカラムに複数の意味をもたせたレガシーな設計に対応しやすい </li></ul></ul><ul><li>より安全 </li></ul><ul><ul><li>違う型で代入しようとすればコンパイルエラー </li></ul></ul>要するに、概念が異なるものは違うクラスでリッチに扱おうよということ。
  7. 7. 宣言的プログラミング – Entity の場合 @Entity public class Employee { @Id private Integer id; private String name; private String phoneNumber; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } // … } @Entity public interface Employee { @Id Identity id(); Name name() ; PhoneNumber phoneNumber() ; // … } よくある一般的なEntity Doma の Entity Doma の Entity はインタフェースで定義する。 メソッドは null を返さない。
  8. 8. 宣言的プログラミング – Dao の場合 @Dao(config = AppConfig.class) public interface EmployeeDao { @Select(fetchSize = 50) Employee selectById(Identity id); @Insert(excludeNull = true) int insert(Employee employee); } Doma の Dao Doma では、アノテーションでクエリの種別を指定する。フェッチサイズ等の指定もアノテーションで記述できる。 意図が明確。間違いにくい。 @S2Dao(bean = Employee.class) public interface EmployeeDao { Employee selectById (Integer id); int insert (Employee employee); } S2DaoのDao S2Daoでは命名規約でクエリの種別を指定。フェッチサイズなどいくつかの設定は設定ファイルで指定。 + 設定ファイル
  9. 9. コンパイル時のコード生成 <ul><li>Pluggable Annotation Processing API を利用 </li></ul><ul><ul><li>Java6 から導入された機能 </li></ul></ul><ul><ul><ul><li>apt と呼ばれることも </li></ul></ul></ul><ul><ul><li>Javac はもちろん Eclipse も対応している </li></ul></ul><ul><ul><ul><li>Save したときにコード生成 </li></ul></ul></ul><ul><ul><ul><li>コードの依存関係をみて賢く生成 </li></ul></ul></ul><ul><ul><ul><li>エラーメッセージをエディタ上に表示 </li></ul></ul></ul>
  10. 10. コンパイル時のコード生成 – 例 @Override public org.seasar.doma.it.entity.Employee selectById(org.seasar.doma.it.domain.Identity employee_id) { entering(&quot;org.seasar.doma.it.dao.EmployeeDao_&quot;, &quot;selectById&quot;, employee_id); if (employee_id == null ) { throw new org.seasar.doma.DomaIllegalArgumentException(&quot;employee_id&quot;, employee_id); } org.seasar.doma.internal.jdbc.query.SqlFileSelectQuery query = new org.seasar.doma.internal.jdbc.query.SqlFileSelectQuery(); query.setConfig(config); query.setSqlFilePath(org.seasar.doma.internal.jdbc.sql.SqlFiles.buildPath(&quot;org.seasar.doma.it.dao.EmployeeDao&quot;, &quot;selectById&quot;)); query.addParameter(&quot;employee_id&quot;, employee_id); query.setCallerClassName(&quot;org.seasar.doma.it.dao.EmployeeDao_&quot;); query.setCallerMethodName(&quot;selectById&quot;); query.setQueryTimeout(-1); query.setMaxRows(-1); query.setFetchSize(-1); query.compile(); org.seasar.doma.internal.jdbc.command.SelectCommand<org.seasar.doma.it.entity.Employee> command = new org.seasar.doma.internal.jdbc.command.SelectCommand<org.seasar.doma.it.entity.Employee>(query, new org.seasar.doma.internal.jdbc.command.EntitySingleResultHandler<org.seasar.doma.it.entity.Employee, org.seasar.doma.it.entity.Employee_>(org.seasar.doma.it.entity.Employee_. class )); org.seasar.doma.it.entity.Employee result = command.execute(); exiting(&quot;org.seasar.doma.it.dao.EmployeeDao_&quot;, &quot;selectById&quot;, result); return result; } @Select Employee selectById(Identity employee_id); インターフェースのメソッド 生成される実装クラスのコード 実行時にリフレクションやAOPで同等のことをするよりも ・パフォーマンスがいい。 ・挙動を把握しやすい。 デバッグがしやすい(デバッグポイントを置きやすい)のもポイント。 利点
  11. 11. Doma の機能 – 概要 <ul><li>複数 RDBMS 対応 </li></ul><ul><ul><li>今は HSQLDB 、 Oracle 、 PostgerSQL 、 MySQL </li></ul></ul><ul><li>2WaySQL </li></ul><ul><ul><li>自動生成 & SQL ファイル </li></ul></ul><ul><li>Entity リスナー </li></ul><ul><ul><li>更新前に汎用的な処理を実行できる </li></ul></ul><ul><ul><ul><li>タイムスタンプや更新者の設定とか </li></ul></ul></ul><ul><li>コンパイル時のエラーチェック </li></ul><ul><ul><li>規約に外れたものをチェック </li></ul></ul><ul><ul><li>SQL ファイルの存在チェック </li></ul></ul><ul><ul><li>コメント式のチェック </li></ul></ul>
  12. 12. Doma の機能 – SQL 関連 <ul><li>検索系 </li></ul><ul><ul><li>Dao のメソッドに @Select をつける </li></ul></ul><ul><ul><li>自動生成しない。 SQL ファイルとのマッピングのみサポート。 </li></ul></ul><ul><ul><li>SQL への変換機能あり(ページング、悲観的ロック)。 </li></ul></ul><ul><ul><li>1 件ずつの処理可能。 </li></ul></ul><ul><li>更新系 </li></ul><ul><ul><li>Dao のメソッドに @Insert 、 @Update などをつける </li></ul></ul><ul><ul><li>自動生成する。 SQL ファイルへのマッピングも可能。 </li></ul></ul><ul><ul><li>Update は変更のあったプロパティのみを対象。 </li></ul></ul><ul><ul><li>バッチ更新にも対応。 </li></ul></ul><ul><li>プロシージャ & ファンクション </li></ul><ul><ul><li>Dao のメソッドに @Procedure や @Function をつける </li></ul></ul>@Procedure(name=&quot;hoge&quot;) void execute (@In Name name, @InOut Salary salary, @Out PhoneNumber phoneNumber); 例
  13. 13. Doma の機能 – SQL ファイル関連 <ul><li>ファイルは Dao ごとに管理 </li></ul><ul><li>SQL コメントのルールは S2Dao に似た感じ </li></ul>select * from employee where name = /*name*/ ’hoge’ select * from employee where /*%if name. startsWith (“A”)*/ name = /*name*/ ’hoge’ --else name isnull /*%end*/ select * from employee where /* %if name != null*/ name = /*name*/ ’hoge’ /* %end */ If 文を使える Method 呼び出し可 else も使える バインド変数はコメントで表す。 メソッドのパラメータ名にあわせる。 @Select selectByName(Name name); Daoのメソッド SQLの例
  14. 14. Doma の機能 – apt 関連 <ul><li>SQLファイルの存在チェック </li></ul><ul><ul><li>SQLファイルが必要なDaoメソッドに対応するファイルが存在しない場合はエラーメッセージを表示。 </li></ul></ul><ul><li>SQLコメントのチェック </li></ul>select * from employee where name = /*emp_name*/ ’hoge’ @Select selectByName(Name name ); メソッドのパラメータに存在しない名前がSQLコメントで使用されたらエラー。
  15. 15. デモ Doma は、 Java6 で動作します。 Java5 以前はサポートしてません。 IDE は Eclipse3.5 で動作することを確認しています。( 3.4 だと動かないところあるかも。) apt をサポートしていれば Eclipse でなくても大丈夫だと思います。 Eclipseで動作させるためのポイント <ul><li>Doma の jar をビルドパスに通す。 </li></ul><ul><li>Doma の jar を ファクトリパス に通す。設定場所は </li></ul><ul><ul><li>プロジェクト右クリック </li></ul></ul><ul><ul><li>- Properties </li></ul></ul><ul><ul><li>- Java Compiler </li></ul></ul><ul><ul><li>- Annotation Processing ( チェックを入れる ) - Factory Path (チェックを入れる、 jar を登録する) </li></ul></ul>動作させるため注意点
  16. 16. まとめ – Doma の良いところ <ul><li>Domain の利用で意図が明確かつ型安全。 </li></ul><ul><li>明示的な設定。 </li></ul><ul><ul><li>命名規約はない。ルールから外れたら apt で通知。 </li></ul></ul><ul><li>Entity や Dao がすっきり。 </li></ul><ul><ul><li>apt でコード生成。 </li></ul></ul><ul><li>SQL を活かす。 </li></ul><ul><ul><li>2WaySQL 。 </li></ul></ul><ul><ul><li>検索系は 意図的に 自動生成なし。ページングや悲観的ロック用の SQL への変換機能はあり。 </li></ul></ul><ul><li>特定のライブラリに依存しない。 </li></ul><ul><li>S2Dao で問題になっていたことがらの多くを解決している。 </li></ul>

×