次世代DaoフレームワークDoma
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 7,200 views

 

Statistics

Views

Total Views
7,200
Views on SlideShare
6,886
Embed Views
314

Actions

Likes
3
Downloads
19
Comments
0

4 Embeds 314

http://d.hatena.ne.jp 296
http://www.slideshare.net 14
http://www.slideee.com 3
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • 次世代 Dao フレームワーク Doma (ドマ) 第 56 回 JavaEE 勉強会 中村年宏 ( http://d.hatena.ne.jp/taedium/)
    • Doma (ドマ)とは
      • D omain O riented MA pping Framework
        • Domain (ドメイン) = 値の定義域
        • Doma では String や Integer の定義域をより狭めたものを Domain (ドメイン)と呼ぶ
      • 名前だけだと汎用的だけど、カテゴリとしては Dao フレームワーク( O/R マッパー)
      • Java6 ( JDBC4.0 )対応
      • 他のライブラリに依存していない
      • Seasar プロジェクトの Sandbox で開発中
        • SVN リポジトリ
          • https://www.seasar.org/svn/sandbox/doma/
        • SNAPSHOT
          • http://maven.seasar.org/maven2-snapshot/org/seasar/doma/doma/0.9.0-SNAPSHOT/
        • ドキュメント
          • なし。。。
    • Doma のコンセプト
      • Domain(ドメイン)中心
      • 宣言的プログラミング
      • コンパイル時のコード自動生成
    • 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 というインタフェースを実装 。
    • 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 インタフェースを実装することも可。 好きなメソッドを定義できる。
    • Domain (ドメイン)中心 – なぜ?
      • 意図を明確に表せる
      • 値に特化したメソッドを持てる
        • PhoneNumber に国番号を扱うメソッドをもつとか
        • ひとつのカラムに複数の意味をもたせたレガシーな設計に対応しやすい
      • より安全
        • 違う型で代入しようとすればコンパイルエラー
      要するに、概念が異なるものは違うクラスでリッチに扱おうよということ。
    • 宣言的プログラミング – 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 を返さない。
    • 宣言的プログラミング – 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では命名規約でクエリの種別を指定。フェッチサイズなどいくつかの設定は設定ファイルで指定。 + 設定ファイル
    • コンパイル時のコード生成
      • Pluggable Annotation Processing API を利用
        • Java6 から導入された機能
          • apt と呼ばれることも
        • Javac はもちろん Eclipse も対応している
          • Save したときにコード生成
          • コードの依存関係をみて賢く生成
          • エラーメッセージをエディタ上に表示
    • コンパイル時のコード生成 – 例 @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で同等のことをするよりも ・パフォーマンスがいい。 ・挙動を把握しやすい。 デバッグがしやすい(デバッグポイントを置きやすい)のもポイント。 利点
    • Doma の機能 – 概要
      • 複数 RDBMS 対応
        • 今は HSQLDB 、 Oracle 、 PostgerSQL 、 MySQL
      • 2WaySQL
        • 自動生成 & SQL ファイル
      • Entity リスナー
        • 更新前に汎用的な処理を実行できる
          • タイムスタンプや更新者の設定とか
      • コンパイル時のエラーチェック
        • 規約に外れたものをチェック
        • SQL ファイルの存在チェック
        • コメント式のチェック
    • Doma の機能 – SQL 関連
      • 検索系
        • Dao のメソッドに @Select をつける
        • 自動生成しない。 SQL ファイルとのマッピングのみサポート。
        • SQL への変換機能あり(ページング、悲観的ロック)。
        • 1 件ずつの処理可能。
      • 更新系
        • Dao のメソッドに @Insert 、 @Update などをつける
        • 自動生成する。 SQL ファイルへのマッピングも可能。
        • Update は変更のあったプロパティのみを対象。
        • バッチ更新にも対応。
      • プロシージャ & ファンクション
        • Dao のメソッドに @Procedure や @Function をつける
      @Procedure(name=&quot;hoge&quot;) void execute (@In Name name, @InOut Salary salary, @Out PhoneNumber phoneNumber); 例
    • Doma の機能 – SQL ファイル関連
      • ファイルは Dao ごとに管理
      • SQL コメントのルールは S2Dao に似た感じ
      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の例
    • Doma の機能 – apt 関連
      • SQLファイルの存在チェック
        • SQLファイルが必要なDaoメソッドに対応するファイルが存在しない場合はエラーメッセージを表示。
      • SQLコメントのチェック
      select * from employee where name = /*emp_name*/ ’hoge’ @Select selectByName(Name name ); メソッドのパラメータに存在しない名前がSQLコメントで使用されたらエラー。
    • デモ Doma は、 Java6 で動作します。 Java5 以前はサポートしてません。 IDE は Eclipse3.5 で動作することを確認しています。( 3.4 だと動かないところあるかも。) apt をサポートしていれば Eclipse でなくても大丈夫だと思います。 Eclipseで動作させるためのポイント
      • Doma の jar をビルドパスに通す。
      • Doma の jar を ファクトリパス に通す。設定場所は
        • プロジェクト右クリック
        • - Properties
        • - Java Compiler
        • - Annotation Processing ( チェックを入れる ) - Factory Path (チェックを入れる、 jar を登録する)
      動作させるため注意点
    • まとめ – Doma の良いところ
      • Domain の利用で意図が明確かつ型安全。
      • 明示的な設定。
        • 命名規約はない。ルールから外れたら apt で通知。
      • Entity や Dao がすっきり。
        • apt でコード生成。
      • SQL を活かす。
        • 2WaySQL 。
        • 検索系は 意図的に 自動生成なし。ページングや悲観的ロック用の SQL への変換機能はあり。
      • 特定のライブラリに依存しない。
      • S2Dao で問題になっていたことがらの多くを解決している。