2

我正在使用休眠。问题在底部。

目前的策略

这很简单。

首先,我有一个基本的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 继承自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. 如果出现 a DaoBook,这个结构就会过时。

所以我变成Dao<T>了一个抽象类,继续重构旧代码。

问题

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

  1. 为每个需要附加的类创建特定的 DAO,这将生成许多几乎为空DaoBook的 s 和排序。
  2. 创建一个拥有 aDao<Object>并仅公开附件方法(即save()update())的类。

我倾向于使用#2,但我认为这种“ AttacherDao”模式可能很糟糕,所以我想听听你的意见。

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

4

3 回答 3

1

我们的方法是为每个持久类创建一个 DAO 对象(从 commonDao 派生)。事实上,我们为这个 DAO 类定义了接口,每个 DAO 决定打开哪些接口。

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

interface PersistentClassDao {
    void save(PersistentClass persistentObject);    
}

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

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

于 2009-06-25T14:52:26.860 回答
0

几个问题

  1. 你是经常创建你的 DAO 来完成一项任务,还是这些长期存在?
  2. 使用静态函数怎么样?显然,您的 Book 对象可以在没有 Book.class 引用的情况下绑定 DAO 函数...

否则,我有点担心保留会话对象而不是获取当前会话的任何内容 - 拥有长期存在的会话对象不是被认为是“坏”的吗?我不是 DAO 的大师,所以也许我在这里遗漏了一些东西。

于 2009-06-23T19:08:35.797 回答
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 之外的数据库代码)相比,这是一个非常小的不便。

于 2009-06-28T00:34:17.987 回答