slim3でやっぱりデータアクセスはDaoクラスでやりたい。

アプリをある程度作成したらやっぱり表題のようにしたいと思ったのでJDODaoというクラス作った。
JDOControllerのソース丸パクリしただけですけどね。

JDODao

import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import org.slim3.jdo.ModelMeta;
import org.slim3.jdo.SelectQuery;

public abstract class JDODao {

    @SuppressWarnings("unused")
    private static final Logger logger = Logger.getLogger(JDODao.class.getName());

    protected PersistenceManager pm;

    protected Transaction tx;

    @Deprecated
    protected JDODao() {
    }

    protected JDODao(PersistenceManager pm) {
        this.pm = pm;
        this.tx = pm.currentTransaction();
    }

    protected <M> SelectQuery<M> from(ModelMeta<M> modelMeta) {
        return new SelectQuery<M>(pm, modelMeta.getModelClass());
    }

    protected <M> SelectQuery<M> from(Class<M> modelClass) {
        return new SelectQuery<M>(pm, modelClass);
    }

    protected <T> T makePersistentInTx(T model) {
        tx.begin();
        T t = pm.makePersistent(model);
        tx.commit();
        return t;
    }

    protected void deletePersistentInTx(Object model) {
        tx.begin();
        pm.deletePersistent(model);
        tx.commit();
    }

    public <T> T makePersistent(T model) {
        T t = pm.makePersistent(model);
        return t;
    }

    public void deletePersistent(Object model) {
        pm.deletePersistent(model);
    }
}

UserDao

public class UserDao extends JDODao {

    protected static UserMeta meta = new UserMeta();

    public UserDao(PersistenceManager pm) {
        super(pm);
    }

    public User find(String key) {
        return from(meta).where(meta.key.eq(key)).getSingleResult();
    }
}

Controller

public class IndexController extends JDOController {
    @Override
    public Navigation run() {
        new UserDao(this.pm).find("1");
        return forward("/user/index.jsp");
    }
}

本当はJDODaoでジェネリクスを使ってUserDaoをこんな風にしたかった。

    public User find(String key) {
        return from().where(key.eq(key)).getSingleResult();
    }
  1. from()にmeta引数不要。
  2. meta.keyじゃなくkey.eqでOK。

1.はできると思うんだけどジェネリクスがよくわかってないことがわかった・・・。
2.はジェネリクスでも無理ぽいけど、まずはどんなシンタックスがいいかを考えてから実装するように考えを変えた。けど実装できずという未熟もの。

追記 slim3本体にGenericDaoとしてサポートされました。

Added GenericDao.

やっぱりMetaModelはジェネリクスだけでは回避できなかったのか。回避しなくてもぜんぜんOKなんですけど。