// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
IBMのサイトに[[HibernateとSpring AOPで、汎用性と型安全性を備えたDAOを作る>http://www-06.ibm.com/jp/developerworks/java/060705/j_j-genericdao.shtml]]という非常に興味深い記事を発見。これは業務アプリを作るときにいつも作成するDAOを効率よく作成する方法をまとめた記事です。通常DAOの作成って、エンティティごとに似たようなコーディングをしなくてはいけなくてひじょーに煩わしいのですが、GenericとSpringを使うことによってこの面倒な作業から解放されます。目からウロコですね。


**やってみる [#ae529dac]
エンティティなどは[[Hibernate/Springを使ってトランザクション処理を記述する]]のものをそのまま流用します。

-DDL
  create table MKINO.USER_ATTR (
  USERID varchar2(100) not null,
  NAME varchar2(1000), primary key (USERID)
 );

#ref(classdiagram.png)



このクラス図で、UserDaoに当たる部分はエンティティごとに実装を書かなくてはいけないのですが、ココを楽することができるようになります。


***まずは基底クラスを作成 [#h38acb25]
UserDaoの既定となるクラスを作成します。
 import java.io.Serializable;
 
 public interface GenericDao<T, PK extends Serializable> {
   PK create(T newInstance);
   T read(PK id);
   void update(T transientObject);
   void delete(T persistentObject);
 }

エンティティに対するCRUDのインタフェースを定義しました。Genericを使ってプライマリキーとエンティティをパラメータ化しているのがポイントです。

次に実装クラスをHibernateとSpringを使って実装します。

 import java.io.Serializable;
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 
 public class GenericDaoHibernateImpl<T, PK extends Serializable> extends
     HibernateDaoSupport implements GenericDao<T, PK> {
   private Class<T> type;
 
   public GenericDaoHibernateImpl(Class<T> type) {
     this.type = type;
   }
 
   public PK create(T o) {
     return (PK) getHibernateTemplate().save(o);
   }
 
   public T read(PK id) {
     return (T) getHibernateTemplate().get(type, id);
   }
 
   public void update(T o) {
     getHibernateTemplate().update(o);
   }
 
   public void delete(T o) {
     getHibernateTemplate().delete(o);
   }
 
 }

実装クラスでも型はパラメータ化されたままになってます。


さて準備はできました。

***インタフェースIUserDaoを作成する [#w8c722bf]
次にUserDaoのインタフェースIUserDaoを作成します。これはココのやり方でなくても作成するいわゆるDAOのインタフェースです。通常は

 import nu.mine.kino.entity.UserAttr;
 
 public interface IUserDao {
   String create(UserAttr newInstance);
   void delete(UserAttr persistentObject);
   UserAttr read(String id);
   void update(UserAttr transientObject);
 }

なんてのを定義するのですが、上のGenericDaoインタフェースを作成したので
 import nu.mine.kino.entity.UserAttr;
 
 public interface IUserDao extends GenericDao<UserAttr, String> {
 }
とテンプレート化された型を指定するだけでOKとなります。ここはエンティティごとに引数や戻り値をちょこちょこ修正して作成するというインタフェースなので、ココの記述が楽になるのはすごくうれしいですね。





***IUserDaoの実装クラスを作成する。 [#ff4e04f7]
次にIUserDaoの実装を作成します。ココも通常は
 import java.util.List;
 import nu.mine.kino.entity.UserAttr;
 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 
 /**
  * @author Masatomi KINO
  * @version $Revision: 1.2 $
  */
 public class UserDao extends HibernateDaoSupport implements IUserDao {
   public String create(UserAttr newInstance) {
     return (String) getHibernateTemplate().save(newInstance);
   }
 
   public void delete(UserAttr persistentObject) {
     getHibernateTemplate().delete(persistentObject);
   }
 
   public UserAttr read(String id) {
     return (UserAttr) getHibernateTemplate().get(UserAttr.class, id);
   }
 
   public void update(UserAttr transientObject) {
     getHibernateTemplate().update(transientObject);
   }
 }

などとやるわけですが、GenericDaoHibernateImplがあるおかげで
 import java.util.List;
 import nu.mine.kino.entity.UserAttr;
 
 /**
  * とりあえず、IUserDaoの実装クラスとして作成したDAOクラス。 実際は、IUserDao (とextends GenericDao<UserAttr,
  * String>)の指定だけで十分なので、このクラスは必要ない。
  * 
  * @author Masatomi KINO
  * @version $Revision: 1.1 $
  */
 public class UserDao extends GenericDaoHibernateImpl<UserAttr, String>
     implements IUserDao {
 
   public UserDao(Class<UserAttr> type) {
     super(type);
   }
 }

となります。



----
この記事は
#vote(おもしろかった,そうでもない)

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS