IBMのサイトにHibernateとSpring AOPで、汎用性と型安全性を備えたDAOを作るという非常に興味深い記事を発見。これは業務アプリを作るときにいつも作成するDAOを効率よく作成する方法をまとめた記事です。通常DAOの作成って、エンティティごとに似たようなコーディングをしなくてはいけなくてひじょーに煩わしいのですが、GenericとSpringを使うことによってこの面倒な作業から解放されます。目からウロコですね。
エンティティなどはHibernate/Springを使ってトランザクション処理を記述するのものをそのまま流用します。
create table MKINO.USER_ATTR ( USERID varchar2(100) not null, NAME varchar2(1000), primary key (USERID) );
このクラス図で、UserDao?に当たる部分はエンティティごとに実装を書かなくてはいけないのですが、ココを楽することができるようになります。
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); } }
実装クラスでも型はパラメータ化されたままになってます。
さて準備はできました。
次に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?の実装を作成します。ココも通常は
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); } }
となります。
この記事は
現在のアクセス:56173