MyBatis + Guice でカンタン DAO 実装(その 2)
前回の続き。
DAO 層の実装(続き)
まずは DAO クラスであることを明示するためのインターフェースを用意*1する。
package jp.mydns.akanekodou.dao.util; import java.util.List; /** * DAO クラス共通インターフェース * * @author Red cat * @param <T> DAO で扱うモデルクラス * @version 1.0 */ public interface Dao<T> { /** * 全件取得 * * @return 全データのリスト */ List<T> all(); }
このインターフェースを実装して、実際の DAO を作る。
package jp.mydns.akanekodou.dao; import com.google.inject.Inject; import java.util.List; import jp.mydns.akanekodou.bean.City; import jp.mydns.akanekodou.dao.mapper.CityMapper; import jp.mydns.akanekodou.dao.util.Dao; /** * City 用 DAO クラス * * @author Red cat * @version 1.0 */ public class CityDAO implements Dao<City> { @Inject private CityMapper mapper; /** * 全件取得 * * @return City の全データのリスト * @see jp.mydns.akanekodou.dao.util.Dao#all() */ @Override public List<City> all() { return mapper.all(); } /** * 主キーを指定して 1 件取得 * * @param id 主キー * @return 指定した主キーを持つ City のデータ */ public City find(int id) { return mapper.find(id); } }
@Inject
アノテーションが付与されたフィールドは、Guice 経由でインスタンス化するときに設定ファイルに従って自動的にインジェクションされる。
一見して CityMapper
と同じ処理をしていて冗長に見えるが、この方が DAO が SQL マッピングファイルから独立していて扱いやすいし、Guice 向けに見ても都合が良い。
最後に、DAO を Guice 経由でインスタンス化するためのユーティリティクラスを作る。
package jp.mydns.akanekodou.dao.util; import org.mybatis.guice.XMLMyBatisModule; import com.google.inject.Guice; import com.google.inject.Injector; /** * DAO 用ユーティリティクラス * * @author Red cat * @version 1.0 */ public class DaoUtil { private Injector injector; // Singleton として実装 private static DaoUtil inst = new DaoUtil(); private DaoUtil() { injector = Guice.createInjector(new XMLMyBatisModule() { @Override protected void initialize() {} }); } /** * DAO クラスのインスタンス取得 * * @param clazz DAO クラス * @return DAO クラスのインスタンス */ public static <T extends Dao<?>> T getDao(Class<T> clazz) { return inst.injector.getInstance(clazz); } }
DAO クラスが Dao
インターフェースを実装するように作ったのは、getDao
の引数に DAO でないクラスが渡せないようにしたかったから。従って Dao
インターフェースを実装していないクラスを引数に渡すとエラーになる。
実際に使うときは
CityDAO dao = DaoUtil.getDao(CityDAO.class);