SlideShare ist ein Scribd-Unternehmen logo
1 von 57
Spring で DAO

船戸隆(エーティーエルシステム
ズ)
鈴木雄介(アークランプ)
目的



• Spring を使って DAO を使う方法を理解する
• DAO を使う場合の注意点を理解する
• 皆がどんな風に DAO を使っているのか共有する
アジェンダ
• DAO とは
• DAO の設計
• Spring で DAO
  – 実装
  – 設定
  – テスト
• GenericDao with Spring
• 気になること
DAO とは
DAO とは
• Data Access
  Object の略
  – J2EE パターンで
    紹介
  – 永続化層におい
    て様々なデータ
    ソースを抽象化
    する
  – 今回は
    RDB ( JDBC)
    前提
                  http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
DAO とは
• メリット
 – SQL が集約されるためメンテナンス性が高い
 – TransferObject になるので Java コードから扱
   いやすい。型重要
• デメリット
 – 他層からデータアクセスの柔軟性が失われる
 – TransferObject を作成するコストが高い
DAO の設計
DAO の設計
• DAO のインターフェース設計
 – CRUD + Finder メソッド
 – パラメタオブジェクトを利用する
 – Tiger 便利
  • TypeSafeEnum
  • Generics
DAO の設計
• CRUD + Finder メソッド
 – CRUD ( Create 、 Read 、 Update 、 Delete
   )は、 TransferObject をまるごとやりとり
   • Read は ID による検索
 – ID 以外の検索は Finder メソッドとして、ある
   程度の目的別に用意
DAO の設計
• パラメタオブジェクトを利用する
   – DAO の Finder メソッドにおいて、パラメタ
     が増えるたびにインターフェースが変わるの
     はいや
   – そこでパラメタオブジェクトとして抽象化
      • パタメタが増えても、 DAO のインターフェースに
public  影響を与えない
      interface BasicDao {
  List findByCriteria(BasicFindCriteria criteria);
}
                           public class BasicFindCriteria {
                             private String someKey;
                           }
DAO の設計
• Tiger 便利( JavaSE5 )
 – 型重要
 – TypeSafeEnum
   public enum AnyEnum {
     type1, type2
   }

 – Generics
   public interface BasicDao {
     List<BasicTransferObject>
        findByCriteria(BasicFindCriteria criteria);
   }
Spring で DAO
Spring で DAO
• 実装のコツ
 – 基本は ORM を使う
 – Spring の ORM サポートクラスを使う
• 設定のコツ
 – AOP でトランザクション設定
• テストのコツ
 – Spring で用意されたテストサポートクラスを
   使う
 – DAO を使うクラスをテストする場合はモック
   を使う
Spring で DAO – 実装
Spring で DAO – 実装
• 基本は ORM を使う
 – とりあえず便利
 – でも無理に使うことはない
• Spring の ORM サポートクラスを使う
 – Exception の違いを吸収
   • Hibernate→HibernateException
   • iBATIS→SQLException
 – try catch を書かなくて済むのでコードがすっきり
 – 例外で処理を判定するコードは書かない
   • org.hibernate.NonUniqueObjectException で判定するな
     ど
Spring で DAO – 実装

• 実装の流れ
  – TransferObject を作る
  – DAO のインターフェースを作る
  – DAO の実装をする
  – マッピングファイル書く
  – Spring に Bean 定義する
• ORM で実装サンプル
  – 今回は Hibernate 、 iBATIS そして・・・
Spring で DAO – 実装
• 実際に DAO を実装してみる



               CREATE TABLE ELECTRIC_GUITAR (
                 ID varchar(40) NOT NULL,
                 NAME varchar(200) ,
                 MANUFACTURE varchar(20),
                 CRAFTED_DATE datetime,
                 PRICE int(11),
                 PRIMARY KEY (ID)
               )
Spring で DAO – 実装
• TransferObject を作る
   public class ElectricGuitar {

     private String id;
                                            Java5 の
                                             Enum
     private String name;

     private ManufactureEnum manufacture;

     private Date craftedDate;

     private Integer price;
           ・
           ・
           ・
Spring で DAO – 実装
• DAO のインターフェースを作る
  public interface ElectricGuitarDao {

      List<ElectricGuitar> findAll();

      ElectricGuitar load(String id);

      String insert(ElectricGuitar electricGuitar);

      void update(ElectricGuitar electricGuitar);

      void delete(ElectricGuitar electricGuitar);

  }
Spring で DAO – 実装
• Hibernate のサンプル
  public class ElectricGuitarHibernateDaoImpl extends
           HibernateDaoSupport implements ElectricGuitarDao {

    public List<ElectricGuitar> findAll() {
      return getHibernateTemplate().loadAll(ElectricGuitar.class);
    }
          ・
          ・
          ・
Spring で DAO – 実装
• マッピングファイルを書く
   – Hibernate のマッピングファイル
 src/main/resources/ElectricGuitar.hbm.xml
<hibernate-mapping package="jp.springframework.vol2.domain">
 <class name="ElectricGuitar" table="ELECTRIC_GUITAR">
  <id name="id" column="ID" type="string" length="40">
   <generator class="uuid" />
  </id>
  <property name="name" column="NAME" type="string" length="200"/>
  <property name="manufacture" column="MANUFACTURE"
   type="jp.springframework.vol2.domain.enums.hibernate.ManufactureType“ length="20"/>
  <property name="craftedDate" column="CRAFTED_DATE" type="timestamp" />
  <property name="price" column="PRICE" type="integer" />
 </class>
Spring で DAO – 実装
 • Spring の設定をする
      –Spring の ApplicationContext の設定
    src/main/resources/context/applicationContextHibernate.xml
    <bean id="electricGuitarDao"
   class="jp.springframework.vol2.dao.hibernate.ElectricGuitarHibernateDaoImpl">
      <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <bean id="sessionFactory"
   class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="mappingLocations">
       <list>
        <value>classpath:hibernate/ElectricGuitar.hbm.xml</value>
       </list>
      </property>

org.hibernate.SessionFactory を組み立てくれる
Spring で DAO – 実装
• iBATIS のサンプル
public class ElectricGuitarIbatisDaoImpl extends SqlMapClientDaoSupport implements
     ElectricGuitarDao {

  public List<ElectricGuitar> findAll() {
    return getSqlMapClientTemplate().queryForList("ElectricGuitar.findAll");
  }

 public ElectricGuitar load(String id) {
   return (ElectricGuitar) getSqlMapClientTemplate().queryForObject("ElectricGuitar.load", id);
 }
   ・
   ・
   ・
Spring で DAO – 実装
• マッピングファイルを書く
 – iBATIS のマッピングファイル
  src/main/resources/ibatis/ElectricGuitar.sqlmap.xml
   <sqlMap namespace="ElectricGuitar">

   <typeAlias alias="guitarParam" type="jp.springframework.vol2.domain.ElectricGuitar"/>

    <resultMap id="guitar" class="jp.springframework.vol2.domain.ElectricGuitar">
     <result property="id" column="ID" />
     <result property="name" column="NAME" />
     <result property="manufacture" column="MANUFACTURE" typeHandler="ManufactureEnum"/>
     <result property="craftedDate" column="CRAFTED_DATE" />
     <result property="price" column="PRICE" />
    </resultMap>

    <select id="findAll" resultMap="guitar">
   SELECT ID, NAME, MANUFACTURE, CRAFTED_DATE, PRICE FROM ELECTRIC_GUITAR
    </select>
      ・
      ・
      ・
Spring で DAO – 実装
   • iBATIS の Spring 設定
    src/main/resources/context/applicationContextIbatis.xml

<bean id="sqlMapClient"
 class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
 <property name="configLocation" value="classpath:ibatis/sqlmap-config.xml" />
 <property name="dataSource" ref="dataSource" />
</bean>
                                                   com.ibatis.sqlmap.client. SqlMapClient を組み立てくれ
                                                   る
<bean id="electricGuitarDao" class="jp.springframework.vol2.dao.ibatis.ElectricGuitarIbatisDaoImpl">
 <property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
Spring で DAO – 実装
• Spring-S2DAO のサンプル
  – S2DAO はインターフェースのみで動作する
    ため実装クラスはありません




Spring-S2Dao
Via:http://d.hatena.ne.jp/n-ichimura/
Spring で DAO – 実装
• S2DAO の設定
 – 基本的に設定レス
 – Java ソースコードにメタデータを記述するだ
   け
 – メソッドを命名規則に合わせることで SQL 文
   の記述が不要
Spring で DAO – 実装
• Spring-S2DAO の Spring の設定
   <bean class="framework.autoregister.FileSystemBeanAutoRegister">
      <property name="addPackageName">
         <value>jp.springframework.vol2.dao</value>
      </property>
      <property name="addClassNames">
         <value>.*Dao</value>
      </property>
      <property name="ignorePackageName">
         <value>jp.springframework.vol2.dao</value>
      </property>
      <property name="ignoreClassNames">
         <value>ElectricGuitarGenericDao,IteratorDao</value>
      </property>
    </bean>

   S2Container の AutoRegister に似た機能
   ( org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister )
   なので個別に DAO の Bean 定義をしません
Spring で DAO – 実装
• ORM サポートクラスは他にもいろいろ
 – org.springframework.orm パッケージ以下
 – Hibernate 、 iBATIS 、 TopLink 、 JPA 、 etc…



 詳しくは
Spring で DAO – 設定
Spring で DAO – 設定
    • AOP でトランザクション設定
        – トランザクション単位を考えよう
        src/main/resources/context/applicationContext-transaction.xml
              <aop:config>
                <aop:advisor pointcut="execution(* *..*MyBusinessLogic.*(..))"
                  advice-ref="txAdvice"/>
               </aop:config>
  Spring 2.X から使え
  る             <tx:advice id="txAdvice">
                <tx:attributes>
                  <tx:method name="calculateAmount" read-only="true"/>
                </tx:attributes>
               </tx:advice>
 ビジネスロジックにトランザクションをかけた場合
その中の DAO のトランザクションはすべて同一になる
Spring で DAO – テス
         ト
Spring で DAO – テスト
• Spring で用意されたテストサポートクラスを使う
  ( org.springframework.test.AbstractTransactionalDataS
  ourceSpringContextTests )
   – Spring のコンテナを自動で初期化してくれる
      @Override
       protected String[] getConfigLocations() {
         return new String[] {"classpath:context/applicationContextHibernate.xml" };
       }


   – Setter があれば自動で Inject してくれる
     private ElectricGuitarDao electricGuitarDao;
     public void setElectricGuitarDao(ElectricGuitarDao newElectricGuitarDao) {
          this.electricGuitarDao = newElectricGuitarDao;
       }



   – 自動でトランザクションの開始&ロールバック
   – テスト用 SQL 実行メソッドがある
     executeSqlScript("classpath:testdata.sql", false);
Spring で DAO – テスト
Hibernate 用 DAO のサンプルコード
    public class ElectricGuitarHibernateDaoImplTest extends
        AbstractTransactionalDataSourceSpringContextTests {

      private ElectricGuitarDao electricGuitarDao;

    public void setElectricGuitarDao(ElectricGuitarDao newElectricGuitarDao) {
        this.electricGuitarDao = newElectricGuitarDao;
      }

      @Override
      protected String[] getConfigLocations() {
        return new String[] {"classpath:context/applicationContextHibernate.xml" };
      }

      public void testInsert() {
        ElectricGuitar guitar = new ElectricGuitar();
        guitar.setManufacture(ManufactureEnum.fender);
        guitar.setName("'56 Stratocaster");
        guitar.setCraftedDate(new Date());
        guitar.setPrice(264320);
        String id = this.electricGuitarDao.insert(guitar);

       assertEquals(id, this.electricGuitarDao.load(id).getId());
     }    
       ・
       ・
Spring で DAO- テスト
• DAO を使うクラスをテストする場
  合はモックを使う
 – 圧倒的なパフォーマンスの差
   • インテグレーションテストを行う際に
     威力を発揮
   • MyBusinessLogicDaoTest
   • MyBusinessLogicMockTest


 – 作業の非同期化
   • DAO の実装なしでもビジネスロジック
     のテストを書ける
Spring で DAO – テスト
•   モックを使った実装サンプル
    –   ビジネスロジック( MyBusinessLogic )では、割
        引入り合計金額計算( calcuateAmount )を行う
Spring で DAO – テスト
• easymock ( http://www.easymock.org/)
• 手順
  1. モックを準備
  2.モックの動きを用意
  3.テストを実施
  4.モックの動きを確認
Spring で DAO – テスト
• 手順 1: モックを準備
   private MyBusinessLogicImpl myBusinessLogicImpl;
   private ElectricGuitarDao mock;

   protected void setUp() {
     mock = createMock(ElectricGuitarDao.class);
     myBusinessLogicImpl = new MyBusinessLogicImpl();
     myBusinessLogicImpl.setElectricGuitarDao(mock);
   }
インターフェースを指定し
てモックを作る
( static import も便利だ
よ)
                   あとは普通に Inject するだ
                   け
Spring で DAO – テスト
• 手順 2: モックの動きを用意
         これを呼ばれる               これが返るよ
         と、
 ElectricGuitar a = new ElectricGuitar();
 a.setManufacture(ManufactureEnum.gretsch);
 a.setPrice(100000);
 expect(mock.load("1")).andReturn(a);
 expectLastCall().times(2);
                                         それを 2 回
 ElectricGuitar b = new ElectricGuitar();
 b.setManufacture(ManufactureEnum.fender);
 b.setPrice(200000);
 expect(mock.load("2")).andReturn(b);
                                 これで用意完
 replay(mock);                   了
Spring で DAO – テスト
   • 手順 3: テストを実施
       – 普通にテストするだけ

long amount = myBusinessLogicImpl.calculateAmount(new String[] {"1" });
assertEquals(80000, amount);

amount = myBusinessLogicImpl.calculateAmount(new String[] {"1", "2" });
assertEquals(260000, amount);
Spring で DAO – テスト
• 手順 4: モックの動きを確認
 – 用意した通りに動いたことを確認


        verify(mock);
GenericDao with Spring
GenericDao with Spring
• GenericDao とは
 – Generics と AOP を使った DAO 支援フレーム
   ワーク
   • http://www-06.ibm.com/jp/developerworks/java/060705/j_j-genericdao.shtml

 – 実装クラスレスで DAO が作れちゃう。 O/R
   マッパのラッパとして非常に便利
 – Spring と一緒に使うべし
   • 今回は Hibernate を利用
GenericDao with Spring

• 実装サンプル
 – Generics を使うことで、型つきの CRUD メ
   ソッドが準備される
 – Finder メソッドは、メソッド名と同じ query
   を用意する
GenericDao with Spring
• インターフェースとマッピングファイル
  だけ interface ElectricGuitarGenericDao
   public
      extends GenericDao<ElectricGuitar, String>{
     public ElectricGuitar findByName(String name);
     public List<ElectricGuitar> findAll();
   }
  <hibernate-mapping package="jp.springframework.vol2.domain">
    <class name="ElectricGuitar" table="ELECTRIC_GUITAR">
      <id name="id" column="ID" type="string" length="40">
      …
    </class>
    <query name="ElectricGuitar.findByName">
      <![CDATA[select e from ElectricGuitar e where e.name = ? ]]>
    </query>
    <query name="ElectricGuitar.findAll">
      <![CDATA[select e from ElectricGuitar e order by e.price]]>
    </query>
  </hibernate-mapping>
GenericDao with Spring
• 仕組み
 – CRUD の実装は普通
 – Finder の実装は AOP


• コード見てね
気になること
気になること
• そもそも O/R マッパって遅い
 – マッピングコストが高い
  • 不必要な項目も取得してしまう
• 現状では解決は難しい
気になること
• 返値 List の Finder で OutOfMemory にな
  る
  – バッチ処理やファイルダウンロード処理であ
    りがち
  – レコードの数だけマッピングしてしまう
• そういう場合は Iterator を使おう
  – next() するごとにマッピング
気になること
• 複数レコードの更新・削除処理が遅い
 – CRUD しかないと、レコードの数だけ
   Update や Delete を繰り返し
• 専用メソッドを用意しよう
 – Update 文や Delete 文
 – StoredProcedure
気になること
• キャッシュしたい
 – DAOでキャッシュ
  • Hibernate は自動でやってくれる
  • OSCache などで自分でキャッシュ
気になること
• パフォーマンス計測したい
       – AOP をつかうと楽
             • Bean 定義したクラスのメソッドの実行時間計測
public class TraceInterceptor implements MethodInterceptor {
  private static Log log = LogFactory.getLog(TraceInterceptor.class);
  public static ThreadLocal<String> local = new ThreadLocal<String>();
  public Object invoke(MethodInvocation invocation) throws Throwable {

      String key = local.get();
      if ( StringUtils.isEmpty(key) || "null".equals(key) ) {
          key = UUID.randomUUID().toString();
          local.set(key);
      }
      log.debug("," + key + "," + System.currentTimeMillis() + "," + getInvocationDescription(invocation) + ",start");
      Object value = invocation.proceed();
      log.debug("," + key + "," + System.currentTimeMillis() + "," + getInvocationDescription(invocation) + ",end");
      return value;
  }
気になること

• N+ 1問題
 – 親レコードの数だけ子レコードを取得
   する SQL が発行されてしまう
   • 注文と注文商品みたいな関係
• Lazy ロードで回避できるが・・・
 – トランザクション注意!
   • トランザクション終了前に子レコードを取
     得する
気になること

• SQL インジェクション攻撃
• プリペアドステートメント推奨
 – SQL の構造が変わらない
 – とはいっても素のステートメントも使
   いたい・・・
  • MySQL のクエリーキャッシュが効かない
  • 使う場合きちんとエスケープする
気になること
• エンティティ露出問題
 – ビュー層で必要とされるモデルとのミスマッチ
    • ビュー層でマスターデータ参照したい
    – マスターにある項目を表示したいのだけど
      TransferObject には ID しかはいっていない・・・
 – 詰め替え問題
  • DTO に誰がどこでつめなおすの?
  • ビジネスロジック層で泣きながら DTO につめる
• 設計上の問題なので解決策があるわけではない
Q&A
ライセンスについて
•   JSUG マスコットアイコン(本スライド左下)が残されている場合に限り、本作品
    (またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。

•   非商用目的に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・
    上演を認めます。

•   本作品のライセンスを遵守する限り、派生作品を頒布することを許可します。

Weitere ähnliche Inhalte

Was ist angesagt?

20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQL20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQLRyusuke Kajiyama
 
sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策scalaconfjp
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)Masatoshi Tada
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaKazuhiro Sera
 
Androidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリAndroidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリYukiya Nakagawa
 
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツ
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツJP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツ
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツHolden Karau
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceWataruOhno
 
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4bitter_fox
 
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)Koichi Sakata
 
初心者エンジニアの システム構築 失敗談
初心者エンジニアの システム構築 失敗談初心者エンジニアの システム構築 失敗談
初心者エンジニアの システム構築 失敗談Makoto Haruyama
 
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cCDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cNorito Agetsuma
 
Java EE パフォーマンスTips #glassfish_jp
Java EE パフォーマンスTips #glassfish_jpJava EE パフォーマンスTips #glassfish_jp
Java EE パフォーマンスTips #glassfish_jpNorito Agetsuma
 
インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)Kentaro Masuda
 
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門だいすけ さとう
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Toshiaki Maki
 
Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Hiroshi Ito
 
thymeleafさいしょの一歩
thymeleafさいしょの一歩thymeleafさいしょの一歩
thymeleafさいしょの一歩Yuichi Hasegawa
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」Hiroyuki Ohnaka
 
AndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使うAndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使うFujimura Munehiko
 

Was ist angesagt? (20)

20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQL20140518 JJUG MySQL Clsuter as NoSQL
20140518 JJUG MySQL Clsuter as NoSQL
 
sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策sbt, past and future / sbt, 傾向と対策
sbt, past and future / sbt, 傾向と対策
 
はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)はまる!JPA(初学者向けライト版)
はまる!JPA(初学者向けライト版)
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
 
Androidで使えるJSON-Javaライブラリ
Androidで使えるJSON-JavaライブラリAndroidで使えるJSON-Javaライブラリ
Androidで使えるJSON-Javaライブラリ
 
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツ
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツJP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツ
JP version - Beyond Shuffling - Apache Spark のスケールアップのためのヒントとコツ
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web Service
 
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
 
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)
クリスマスを支える俺たちとJava(JJUG CCC 2015 Spring AB4)
 
初心者エンジニアの システム構築 失敗談
初心者エンジニアの システム構築 失敗談初心者エンジニアの システム構築 失敗談
初心者エンジニアの システム構築 失敗談
 
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4cCDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
 
Java EE パフォーマンスTips #glassfish_jp
Java EE パフォーマンスTips #glassfish_jpJava EE パフォーマンスTips #glassfish_jp
Java EE パフォーマンスTips #glassfish_jp
 
インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)インターンシップの学生にお届けしようとしたScalaの文法(初級編)
インターンシップの学生にお届けしようとしたScalaの文法(初級編)
 
Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門Ruby on Rails on MySQL チューニング入門
Ruby on Rails on MySQL チューニング入門
 
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
 
Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks Reladomo in Scala #scala_ks
Reladomo in Scala #scala_ks
 
thymeleafさいしょの一歩
thymeleafさいしょの一歩thymeleafさいしょの一歩
thymeleafさいしょの一歩
 
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
JavaOne 2015 報告会 @ 東京 「About MVC 1.0 & JSON-P」
 
AndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使うAndroidでActiveRecordライクにDBを使う
AndroidでActiveRecordライクにDBを使う
 

Ähnlich wie Springでdao 20070413

Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
scala+liftで遊ぼう
scala+liftで遊ぼうscala+liftで遊ぼう
scala+liftで遊ぼうyouku
 
ASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうDevTakas
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜Naohiro Yoshida
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624Yusuke Suzuki
 
SDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireSDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireAkio Katayama
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略takezoe
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようAkira Shimosako
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Daisuke Hiraoka
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングkunihikokaneko1
 
REST with Spring Boot #jqfk
REST with Spring Boot #jqfkREST with Spring Boot #jqfk
REST with Spring Boot #jqfkToshiaki Maki
 
Java ee6 with scala
Java ee6 with scalaJava ee6 with scala
Java ee6 with scalaSatoshi Kubo
 
Gradleどうでしょう
GradleどうでしょうGradleどうでしょう
GradleどうでしょうTakuma Watabiki
 
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-PE-BANK
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッションYuichi Hasegawa
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Masahiro Nagano
 

Ähnlich wie Springでdao 20070413 (20)

Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
scala+liftで遊ぼう
scala+liftで遊ぼうscala+liftで遊ぼう
scala+liftで遊ぼう
 
ASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おうASP.NET Core WebAPIでODataを使おう
ASP.NET Core WebAPIでODataを使おう
 
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜Spring Framework / Boot / Data 徹底活用  〜Spring Data Redis 編〜
Spring Framework / Boot / Data 徹底活用 〜Spring Data Redis 編〜
 
企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624企業におけるSpring@日本springユーザー会20090624
企業におけるSpring@日本springユーザー会20090624
 
SDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireSDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 Whire
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみよう
 
Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!
 
Sc2009autumn s2robot
Sc2009autumn s2robotSc2009autumn s2robot
Sc2009autumn s2robot
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピングpi-15. カプセル化, MVCモデル, オブジェクトのマッピング
pi-15. カプセル化, MVCモデル, オブジェクトのマッピング
 
REST with Spring Boot #jqfk
REST with Spring Boot #jqfkREST with Spring Boot #jqfk
REST with Spring Boot #jqfk
 
scala-kaigi1-sbt
scala-kaigi1-sbtscala-kaigi1-sbt
scala-kaigi1-sbt
 
Java ee6 with scala
Java ee6 with scalaJava ee6 with scala
Java ee6 with scala
 
Gradleどうでしょう
GradleどうでしょうGradleどうでしょう
Gradleどうでしょう
 
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
 
Jjug springセッション
Jjug springセッションJjug springセッション
Jjug springセッション
 
Spring3.1概要x di
Spring3.1概要x diSpring3.1概要x di
Spring3.1概要x di
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
 

Mehr von Funato Takashi

プログラムを作って飯を食うということ
プログラムを作って飯を食うということプログラムを作って飯を食うということ
プログラムを作って飯を食うということFunato Takashi
 
Unit testで定時帰宅!
Unit testで定時帰宅!Unit testで定時帰宅!
Unit testで定時帰宅!Funato Takashi
 
スレッドダンプの読み方
スレッドダンプの読み方スレッドダンプの読み方
スレッドダンプの読み方Funato Takashi
 

Mehr von Funato Takashi (7)

プログラムを作って飯を食うということ
プログラムを作って飯を食うということプログラムを作って飯を食うということ
プログラムを作って飯を食うということ
 
Git flow cheatsheet
Git flow cheatsheetGit flow cheatsheet
Git flow cheatsheet
 
Unit testで定時帰宅!
Unit testで定時帰宅!Unit testで定時帰宅!
Unit testで定時帰宅!
 
Maven2 plugin
Maven2 pluginMaven2 plugin
Maven2 plugin
 
問題解決ノ勘所
問題解決ノ勘所問題解決ノ勘所
問題解決ノ勘所
 
Javaでmongo db
Javaでmongo dbJavaでmongo db
Javaでmongo db
 
スレッドダンプの読み方
スレッドダンプの読み方スレッドダンプの読み方
スレッドダンプの読み方
 

Springでdao 20070413

  • 2. 目的 • Spring を使って DAO を使う方法を理解する • DAO を使う場合の注意点を理解する • 皆がどんな風に DAO を使っているのか共有する
  • 3. アジェンダ • DAO とは • DAO の設計 • Spring で DAO – 実装 – 設定 – テスト • GenericDao with Spring • 気になること
  • 5. DAO とは • Data Access Object の略 – J2EE パターンで 紹介 – 永続化層におい て様々なデータ ソースを抽象化 する – 今回は RDB ( JDBC) 前提 http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
  • 6. DAO とは • メリット – SQL が集約されるためメンテナンス性が高い – TransferObject になるので Java コードから扱 いやすい。型重要 • デメリット – 他層からデータアクセスの柔軟性が失われる – TransferObject を作成するコストが高い
  • 8. DAO の設計 • DAO のインターフェース設計 – CRUD + Finder メソッド – パラメタオブジェクトを利用する – Tiger 便利 • TypeSafeEnum • Generics
  • 9. DAO の設計 • CRUD + Finder メソッド – CRUD ( Create 、 Read 、 Update 、 Delete )は、 TransferObject をまるごとやりとり • Read は ID による検索 – ID 以外の検索は Finder メソッドとして、ある 程度の目的別に用意
  • 10. DAO の設計 • パラメタオブジェクトを利用する – DAO の Finder メソッドにおいて、パラメタ が増えるたびにインターフェースが変わるの はいや – そこでパラメタオブジェクトとして抽象化 • パタメタが増えても、 DAO のインターフェースに public 影響を与えない interface BasicDao { List findByCriteria(BasicFindCriteria criteria); } public class BasicFindCriteria { private String someKey; }
  • 11. DAO の設計 • Tiger 便利( JavaSE5 ) – 型重要 – TypeSafeEnum public enum AnyEnum { type1, type2 } – Generics public interface BasicDao { List<BasicTransferObject> findByCriteria(BasicFindCriteria criteria); }
  • 13. Spring で DAO • 実装のコツ – 基本は ORM を使う – Spring の ORM サポートクラスを使う • 設定のコツ – AOP でトランザクション設定 • テストのコツ – Spring で用意されたテストサポートクラスを 使う – DAO を使うクラスをテストする場合はモック を使う
  • 14. Spring で DAO – 実装
  • 15. Spring で DAO – 実装 • 基本は ORM を使う – とりあえず便利 – でも無理に使うことはない • Spring の ORM サポートクラスを使う – Exception の違いを吸収 • Hibernate→HibernateException • iBATIS→SQLException – try catch を書かなくて済むのでコードがすっきり – 例外で処理を判定するコードは書かない • org.hibernate.NonUniqueObjectException で判定するな ど
  • 16. Spring で DAO – 実装 • 実装の流れ – TransferObject を作る – DAO のインターフェースを作る – DAO の実装をする – マッピングファイル書く – Spring に Bean 定義する • ORM で実装サンプル – 今回は Hibernate 、 iBATIS そして・・・
  • 17. Spring で DAO – 実装 • 実際に DAO を実装してみる CREATE TABLE ELECTRIC_GUITAR ( ID varchar(40) NOT NULL, NAME varchar(200) , MANUFACTURE varchar(20), CRAFTED_DATE datetime, PRICE int(11), PRIMARY KEY (ID) )
  • 18. Spring で DAO – 実装 • TransferObject を作る public class ElectricGuitar { private String id; Java5 の Enum private String name; private ManufactureEnum manufacture; private Date craftedDate; private Integer price; ・ ・ ・
  • 19. Spring で DAO – 実装 • DAO のインターフェースを作る public interface ElectricGuitarDao { List<ElectricGuitar> findAll(); ElectricGuitar load(String id); String insert(ElectricGuitar electricGuitar); void update(ElectricGuitar electricGuitar); void delete(ElectricGuitar electricGuitar); }
  • 20. Spring で DAO – 実装 • Hibernate のサンプル public class ElectricGuitarHibernateDaoImpl extends HibernateDaoSupport implements ElectricGuitarDao { public List<ElectricGuitar> findAll() { return getHibernateTemplate().loadAll(ElectricGuitar.class); } ・ ・ ・
  • 21. Spring で DAO – 実装 • マッピングファイルを書く – Hibernate のマッピングファイル src/main/resources/ElectricGuitar.hbm.xml <hibernate-mapping package="jp.springframework.vol2.domain"> <class name="ElectricGuitar" table="ELECTRIC_GUITAR"> <id name="id" column="ID" type="string" length="40"> <generator class="uuid" /> </id> <property name="name" column="NAME" type="string" length="200"/> <property name="manufacture" column="MANUFACTURE" type="jp.springframework.vol2.domain.enums.hibernate.ManufactureType“ length="20"/> <property name="craftedDate" column="CRAFTED_DATE" type="timestamp" /> <property name="price" column="PRICE" type="integer" /> </class>
  • 22. Spring で DAO – 実装 • Spring の設定をする –Spring の ApplicationContext の設定 src/main/resources/context/applicationContextHibernate.xml <bean id="electricGuitarDao" class="jp.springframework.vol2.dao.hibernate.ElectricGuitarHibernateDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations"> <list> <value>classpath:hibernate/ElectricGuitar.hbm.xml</value> </list> </property> org.hibernate.SessionFactory を組み立てくれる
  • 23. Spring で DAO – 実装 • iBATIS のサンプル public class ElectricGuitarIbatisDaoImpl extends SqlMapClientDaoSupport implements ElectricGuitarDao { public List<ElectricGuitar> findAll() { return getSqlMapClientTemplate().queryForList("ElectricGuitar.findAll"); } public ElectricGuitar load(String id) { return (ElectricGuitar) getSqlMapClientTemplate().queryForObject("ElectricGuitar.load", id); }    ・    ・    ・
  • 24. Spring で DAO – 実装 • マッピングファイルを書く – iBATIS のマッピングファイル src/main/resources/ibatis/ElectricGuitar.sqlmap.xml <sqlMap namespace="ElectricGuitar"> <typeAlias alias="guitarParam" type="jp.springframework.vol2.domain.ElectricGuitar"/> <resultMap id="guitar" class="jp.springframework.vol2.domain.ElectricGuitar"> <result property="id" column="ID" /> <result property="name" column="NAME" /> <result property="manufacture" column="MANUFACTURE" typeHandler="ManufactureEnum"/> <result property="craftedDate" column="CRAFTED_DATE" /> <result property="price" column="PRICE" /> </resultMap> <select id="findAll" resultMap="guitar"> SELECT ID, NAME, MANUFACTURE, CRAFTED_DATE, PRICE FROM ELECTRIC_GUITAR </select>    ・    ・    ・
  • 25. Spring で DAO – 実装 • iBATIS の Spring 設定 src/main/resources/context/applicationContextIbatis.xml <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:ibatis/sqlmap-config.xml" /> <property name="dataSource" ref="dataSource" /> </bean> com.ibatis.sqlmap.client. SqlMapClient を組み立てくれ る <bean id="electricGuitarDao" class="jp.springframework.vol2.dao.ibatis.ElectricGuitarIbatisDaoImpl"> <property name="sqlMapClient" ref="sqlMapClient"/> </bean>
  • 26. Spring で DAO – 実装 • Spring-S2DAO のサンプル – S2DAO はインターフェースのみで動作する ため実装クラスはありません Spring-S2Dao Via:http://d.hatena.ne.jp/n-ichimura/
  • 27. Spring で DAO – 実装 • S2DAO の設定 – 基本的に設定レス – Java ソースコードにメタデータを記述するだ け – メソッドを命名規則に合わせることで SQL 文 の記述が不要
  • 28. Spring で DAO – 実装 • Spring-S2DAO の Spring の設定 <bean class="framework.autoregister.FileSystemBeanAutoRegister"> <property name="addPackageName"> <value>jp.springframework.vol2.dao</value> </property> <property name="addClassNames"> <value>.*Dao</value> </property> <property name="ignorePackageName"> <value>jp.springframework.vol2.dao</value> </property> <property name="ignoreClassNames"> <value>ElectricGuitarGenericDao,IteratorDao</value> </property> </bean> S2Container の AutoRegister に似た機能 ( org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister ) なので個別に DAO の Bean 定義をしません
  • 29. Spring で DAO – 実装 • ORM サポートクラスは他にもいろいろ – org.springframework.orm パッケージ以下 – Hibernate 、 iBATIS 、 TopLink 、 JPA 、 etc… 詳しくは
  • 30. Spring で DAO – 設定
  • 31. Spring で DAO – 設定 • AOP でトランザクション設定 – トランザクション単位を考えよう src/main/resources/context/applicationContext-transaction.xml <aop:config> <aop:advisor pointcut="execution(* *..*MyBusinessLogic.*(..))"     advice-ref="txAdvice"/> </aop:config> Spring 2.X から使え る <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="calculateAmount" read-only="true"/> </tx:attributes> </tx:advice> ビジネスロジックにトランザクションをかけた場合 その中の DAO のトランザクションはすべて同一になる
  • 32. Spring で DAO – テス ト
  • 33. Spring で DAO – テスト • Spring で用意されたテストサポートクラスを使う ( org.springframework.test.AbstractTransactionalDataS ourceSpringContextTests ) – Spring のコンテナを自動で初期化してくれる @Override protected String[] getConfigLocations() { return new String[] {"classpath:context/applicationContextHibernate.xml" }; } – Setter があれば自動で Inject してくれる private ElectricGuitarDao electricGuitarDao; public void setElectricGuitarDao(ElectricGuitarDao newElectricGuitarDao) { this.electricGuitarDao = newElectricGuitarDao; } – 自動でトランザクションの開始&ロールバック – テスト用 SQL 実行メソッドがある executeSqlScript("classpath:testdata.sql", false);
  • 34. Spring で DAO – テスト Hibernate 用 DAO のサンプルコード public class ElectricGuitarHibernateDaoImplTest extends AbstractTransactionalDataSourceSpringContextTests { private ElectricGuitarDao electricGuitarDao; public void setElectricGuitarDao(ElectricGuitarDao newElectricGuitarDao) { this.electricGuitarDao = newElectricGuitarDao; } @Override protected String[] getConfigLocations() { return new String[] {"classpath:context/applicationContextHibernate.xml" }; } public void testInsert() { ElectricGuitar guitar = new ElectricGuitar(); guitar.setManufacture(ManufactureEnum.fender); guitar.setName("'56 Stratocaster"); guitar.setCraftedDate(new Date()); guitar.setPrice(264320); String id = this.electricGuitarDao.insert(guitar); assertEquals(id, this.electricGuitarDao.load(id).getId()); }        ・    ・
  • 35. Spring で DAO- テスト • DAO を使うクラスをテストする場 合はモックを使う – 圧倒的なパフォーマンスの差 • インテグレーションテストを行う際に 威力を発揮 • MyBusinessLogicDaoTest • MyBusinessLogicMockTest – 作業の非同期化 • DAO の実装なしでもビジネスロジック のテストを書ける
  • 36. Spring で DAO – テスト • モックを使った実装サンプル – ビジネスロジック( MyBusinessLogic )では、割 引入り合計金額計算( calcuateAmount )を行う
  • 37. Spring で DAO – テスト • easymock ( http://www.easymock.org/) • 手順 1. モックを準備 2.モックの動きを用意 3.テストを実施 4.モックの動きを確認
  • 38. Spring で DAO – テスト • 手順 1: モックを準備 private MyBusinessLogicImpl myBusinessLogicImpl; private ElectricGuitarDao mock; protected void setUp() { mock = createMock(ElectricGuitarDao.class); myBusinessLogicImpl = new MyBusinessLogicImpl(); myBusinessLogicImpl.setElectricGuitarDao(mock); } インターフェースを指定し てモックを作る ( static import も便利だ よ) あとは普通に Inject するだ け
  • 39. Spring で DAO – テスト • 手順 2: モックの動きを用意 これを呼ばれる これが返るよ と、 ElectricGuitar a = new ElectricGuitar(); a.setManufacture(ManufactureEnum.gretsch); a.setPrice(100000); expect(mock.load("1")).andReturn(a); expectLastCall().times(2); それを 2 回 ElectricGuitar b = new ElectricGuitar(); b.setManufacture(ManufactureEnum.fender); b.setPrice(200000); expect(mock.load("2")).andReturn(b); これで用意完 replay(mock); 了
  • 40. Spring で DAO – テスト • 手順 3: テストを実施 – 普通にテストするだけ long amount = myBusinessLogicImpl.calculateAmount(new String[] {"1" }); assertEquals(80000, amount); amount = myBusinessLogicImpl.calculateAmount(new String[] {"1", "2" }); assertEquals(260000, amount);
  • 41. Spring で DAO – テスト • 手順 4: モックの動きを確認 – 用意した通りに動いたことを確認 verify(mock);
  • 43. GenericDao with Spring • GenericDao とは – Generics と AOP を使った DAO 支援フレーム ワーク • http://www-06.ibm.com/jp/developerworks/java/060705/j_j-genericdao.shtml – 実装クラスレスで DAO が作れちゃう。 O/R マッパのラッパとして非常に便利 – Spring と一緒に使うべし • 今回は Hibernate を利用
  • 44. GenericDao with Spring • 実装サンプル – Generics を使うことで、型つきの CRUD メ ソッドが準備される – Finder メソッドは、メソッド名と同じ query を用意する
  • 45. GenericDao with Spring • インターフェースとマッピングファイル だけ interface ElectricGuitarGenericDao public extends GenericDao<ElectricGuitar, String>{ public ElectricGuitar findByName(String name); public List<ElectricGuitar> findAll(); } <hibernate-mapping package="jp.springframework.vol2.domain"> <class name="ElectricGuitar" table="ELECTRIC_GUITAR"> <id name="id" column="ID" type="string" length="40"> … </class> <query name="ElectricGuitar.findByName"> <![CDATA[select e from ElectricGuitar e where e.name = ? ]]> </query> <query name="ElectricGuitar.findAll"> <![CDATA[select e from ElectricGuitar e order by e.price]]> </query> </hibernate-mapping>
  • 46. GenericDao with Spring • 仕組み – CRUD の実装は普通 – Finder の実装は AOP • コード見てね
  • 48. 気になること • そもそも O/R マッパって遅い – マッピングコストが高い • 不必要な項目も取得してしまう • 現状では解決は難しい
  • 49. 気になること • 返値 List の Finder で OutOfMemory にな る – バッチ処理やファイルダウンロード処理であ りがち – レコードの数だけマッピングしてしまう • そういう場合は Iterator を使おう – next() するごとにマッピング
  • 50. 気になること • 複数レコードの更新・削除処理が遅い – CRUD しかないと、レコードの数だけ Update や Delete を繰り返し • 専用メソッドを用意しよう – Update 文や Delete 文 – StoredProcedure
  • 51. 気になること • キャッシュしたい – DAOでキャッシュ • Hibernate は自動でやってくれる • OSCache などで自分でキャッシュ
  • 52. 気になること • パフォーマンス計測したい – AOP をつかうと楽 • Bean 定義したクラスのメソッドの実行時間計測 public class TraceInterceptor implements MethodInterceptor { private static Log log = LogFactory.getLog(TraceInterceptor.class); public static ThreadLocal<String> local = new ThreadLocal<String>(); public Object invoke(MethodInvocation invocation) throws Throwable { String key = local.get(); if ( StringUtils.isEmpty(key) || "null".equals(key) ) { key = UUID.randomUUID().toString(); local.set(key); } log.debug("," + key + "," + System.currentTimeMillis() + "," + getInvocationDescription(invocation) + ",start"); Object value = invocation.proceed(); log.debug("," + key + "," + System.currentTimeMillis() + "," + getInvocationDescription(invocation) + ",end"); return value; }
  • 53. 気になること • N+ 1問題 – 親レコードの数だけ子レコードを取得 する SQL が発行されてしまう • 注文と注文商品みたいな関係 • Lazy ロードで回避できるが・・・ – トランザクション注意! • トランザクション終了前に子レコードを取 得する
  • 54. 気になること • SQL インジェクション攻撃 • プリペアドステートメント推奨 – SQL の構造が変わらない – とはいっても素のステートメントも使 いたい・・・ • MySQL のクエリーキャッシュが効かない • 使う場合きちんとエスケープする
  • 55. 気になること • エンティティ露出問題 – ビュー層で必要とされるモデルとのミスマッチ • ビュー層でマスターデータ参照したい – マスターにある項目を表示したいのだけど TransferObject には ID しかはいっていない・・・ – 詰め替え問題 • DTO に誰がどこでつめなおすの? • ビジネスロジック層で泣きながら DTO につめる • 設計上の問題なので解決策があるわけではない
  • 56. Q&A
  • 57. ライセンスについて • JSUG マスコットアイコン(本スライド左下)が残されている場合に限り、本作品 (またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。 • 非商用目的に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・ 上演を認めます。 • 本作品のライセンスを遵守する限り、派生作品を頒布することを許可します。