我的DAO策略好吗?

时间:2009-06-22 22:46:33

标签: java hibernate dao

我正在使用Hibernate。问题出在底部。

当前策略

很简单。

首先,我有一个基本的Dao<T>

public class Dao<T> {
    private Class<T> persistentClass;
    private Session session;

    public Dao(Class<T> persistentClass) {
        this.persistenClass = persistentClass;
        this.session = HibernateUtil.getCurrentSession();
    }

它作为基类很好用,它将最常用的方法传递到Session

    public T get(Serializable id) {
        @SuppressWarnings("unchecked")
        T t = (T) this.session.get(this.persistentClass, id);

        return t;
    }

    protected Criteria getCriteria() {
        return this.session.createCriteria(this.persistentClass);
    }

当需要在模型上使用查询时,它会进入该模型的特定DAO,该模型继承自Dao<T>

public class DaoTask extends Dao<Task> {
    public DaoTask() {
        super(Task.class);
    }

    public List<Task> searchActiveTasks() {
        @SuppressWarnings("unchecked")
        List<Task> list = (List<Task>) this.getCriteria()
            .add(Restrictions.eq("active", true))
            .list();

        return list;
    }
}

这种方法一直运作良好。

然而...

然而,今天我发现很多时候实例需要重新附加到Session,并且会出现类似于以下内容的行:

new Dao<Book>(Book.class).update(book);

......我觉得这很糟糕,因为

  1. 我不喜欢指定多余的Book.class
  2. 如果出现DaoBook,此构造将变得过时。
  3. 所以我将Dao<T>变成了一个抽象类,然后继续重构旧代码。

    问题

    为了从代码库中删除Dao<T>引用,我想到了两种方法:

    1. 为每个需要附件的类创建特定的DAO,这将生成许多几乎为空的DaoBook和排序。
    2. 创建一个拥有Dao<Object>的类,并仅公开附件方法(例如save()update()等)。
    3. 我倾向于选择#2,但我认为这种“AttacherDao”模式可能不好,所以我希望你的意见。

      #2的任何缺点?另外,你觉得“当前战略”有什么问题吗?

3 个答案:

答案 0 :(得分:1)

我们的方法是为每个持久化类提供DAO对象(从commonDao派生)。实际上,我们为这个DAO类定义接口,每个DAO决定打开哪些接口。

使用以下代码,用户无法删除PersistentClass

interface PersistentClassDao {
    void save(PersistentClass persistentObject);    
}

Class PersistentClassDaoImpl extends CommonDao implements PersistentClassDao {
        void save(persistentObject) {
    persist(persistentObject);
}

即使它有一些额外的开销,这种方法有助于在暴露接口之前对适当的代码进行单元测试。

答案 1 :(得分:0)

几个问题

  1. 您经常创建DAO来执行单个任务还是长期存在?
  2. 使用静态功能怎么样?显然,您的Book对象可以绑定DAO函数,而不需要Book.class引用...
  3. 否则,我有点担心保持会话对象而不是获取当前会话的任何内容 - 对于长期存在的会话对象,它不被认为是“坏”吗?我不是DAO的主人,所以也许我在这里错过了一些东西。

答案 2 :(得分:0)

我们选择了类似于lud0h的方法,但有以下几点:

abstract class<T extends IModelObject> JdbcCrudDao<T>{

   void create(T dbo){}
   T findByFoo(String foo){}
   void update(T dbo){}
   void delete(T dbo){}

}

class BarDao extends JdbcCrudDao<Bar>{

}

但是,扭曲的是我们选择性地通过立面暴露Dao上的方法,只转发我们绝对必须的那些。

class BarController implements IController{

    private static final BarDao dao;
    // ...

    void update( IBar bar ){
       dao.update(bar);
    }

}

所有这一切中唯一的缺点是,如果你想在接口类型(我们这样做)之后隐藏你的数据库密钥,它需要一些演员,但这是一个非常小的不便与替代(数据库代码之外) DAOS)。