我的 DAO 策略可以吗?

发布于 2024-07-25 18:20:26 字数 1959 浏览 3 评论 0原文

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

目前的策略

很简单。

首先,我有一个基本的Dao

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

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,这个构造将变得过时。

于是我把 Dao 变成了一个抽象类,然后继续重构旧代码。

问题

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

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

我倾向于选择#2,但我认为这个“AttacherDao”模式可能不好,所以我想听听你的意见。

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

I'm using Hibernate. The question is at the bottom.

The current strategy

It's simple.

First of all, I have a basic 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();
    }

It's nice as a base class and it passes the most common methods up to its 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);
    }

When there's need to use queries on the model, it goes into a specific DAO for that piece of model, which inherits from 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;
    }
}

This approach has always worked well.

However...

However, today I found that many times an instance needs reattachment to the Session and a line similar to the following ends up happening:

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

... which I find to be bad, because

  1. I don't like specifying the redundant Book.class
  2. If ever a DaoBook arises, this construct will become obsolete.

So I turned Dao<T> into an abstract class, and went on to refactor the old code.

Question

In order to remove the Dao<T> references from the codebase, I thought of two approaches:

  1. Create specific DAOs for every class that ever needs attachment, which would generate many almost empty DaoBooks and the sort.
  2. Create a class that owns a Dao<Object> and exposes only the attachment methods (i.e. save(), update() etc).

I'm tending to go with #2, but I thought this "AttacherDao" pattern might be bad, so I'd like your opinion.

Any cons for #2? Also, do you find anything wrong with "the current strategy"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

人间☆小暴躁 2024-08-01 18:20:26

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

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

interface PersistentClassDao {
    void save(PersistentClass persistentObject);    
}

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

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

Our approach is to have a DAO object (derived from a commonDao) for each persistent class. In fact we define interface for this DAO class and each DAO decides which interfaces are opened up.

Using the following code, user cannot delete the PersistentClass.

interface PersistentClassDao {
    void save(PersistentClass persistentObject);    
}

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

Even though it has some additional overhead, this approach helps in unit testing appropriate code before exposing an interface.

十级心震 2024-08-01 18:20:26

我们选择了与 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 之外的数据库代码)相比,这是一个相当小的不便。

We've chosen an approach similar to lud0h's, with the following twist:

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>{

}

But, the twist is that we selectively expose methods on the Dao through a facade and forward only those we absolutely must.

class BarController implements IController{

    private static final BarDao dao;
    // ...

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

}

The only short-coming in all this is it requires some casting about if you wish to hide your database keys behind an interface type (which we do), but it's a pretty minor inconvenience versus the alternative (database code outside of the Daos).

口干舌燥 2024-08-01 18:20:26

几个问题

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

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

Couple of questions

  1. Are you frequently creating your DAO to do a single task or are these long lived?
  2. What about using a static function? Clearly your Book object can be bind the DAO function to without the Book.class reference...

Otherwise, I'm a little worried about keeping the session object around instead of fetching whatever the current session is - isn't it considered "bad" to have long lived session objects? I'm not a master of DAO, so maybe I'm missing something here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文