通用 DAO 如何为所有不同的 DAO 实现返回相同的类型?

Posted

技术标签:

【中文标题】通用 DAO 如何为所有不同的 DAO 实现返回相同的类型?【英文标题】:How generic DAO can return same type for all different DAO implementations? 【发布时间】:2012-09-15 16:48:16 【问题描述】:

我正在为我的 DataNucleus JDO DAO 创建通用 DAO。通用 DAO 将执行获取、更新、删除、创建操作和一些其他通用操作,因此这些实现可以在更具体的 DAO 中进行扩展。

是否有可能以某种方式扩展通用 DAO 并让它在例如通过 id 获取对象时返回正确的类型?

User user = userDao.get(userId); // Is this possible when UserDao extends generic DAO ?? userDao should return user of type User instead of object.

【问题讨论】:

【参考方案1】:

是的,可以使用泛型来做到这一点:

public abstract class Dao<T> 
    public T get(String id)  ... 

    ...


public class UserDao extends Dao<User> 
    ...


UserDao userDao = new UserDao();
User user = userDao.get(userId); //Returns a User

根据您的需要,Dao&lt;T&gt; 可以是抽象基类,也可以是通用接口(例如 public interface IDao&lt;T&gt; ...

【讨论】:

哎呀我完全错过了这个问题被标记为 java 而不是 C#,但同样的事情在两者中都有效。我已经更新了我 认为 是正确的 java 语法的答案,但我生疏了,并且在这台机器上没有任何 java 的东西要检查。如果我犯了任何语法错误,我深表歉意,我会尽可能地纠正它们! @versesmarald 你应该更喜欢组合而不是继承。看我的回答。【参考方案2】:

verdesmarald 已经回答了您的部分问题。我想在 verdesmarald 的代码中添加一项重要更改

你应该更喜欢组合而不是继承。 UserDao 应该有一个 Dao,而不是从 Dao 扩展 UserDao。这样,您的代码将不会绑定到单个实现,并且可以在单元测试期间模拟 Dao。

【讨论】:

你的意思是我应该通过构造函数将通用 dao 添加到 UserDao 吗?还是我误解了你的意思? 我不同意 - 通用 DAO 通常是具有单个实现的接口。不涉及继承或组合。建议很好,但不是在这种情况下。 @newbie 没错。 UserDao 应该有一个 Dao 实例变量和一个接受 Dao 类型参数的构造函数。同样,每个 XYZDao 类都可以有一个以 Dao 作为参数的构造函数。在进行单元测试时,您可以传入 Dao 的一个子类,该子类通过打印一条消息并在没有任何实际数据库操作的情况下返回来简单地模拟数据库调用。 您错过的一点是没有必要扩展通用 DAO 来创建用户 DAO。您只需实例化一个将参数化类型设置为 User 的实例。上面带“extends”的代码不正确。 @duffymo。说得通。如果不需要延伸道,那我就更正了。在这种情况下,上下文很重要!我的错!

以上是关于通用 DAO 如何为所有不同的 DAO 实现返回相同的类型?的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis是如何为Dao接口创建实现类的

你如何为 Seam / JPA (hibernate) 创建一个 DAO 类?

使用mybatis完成通用dao和通用service

Java/Hibernate:如何为复杂的 SQL 编写 DAO 代码

为 Hibernate 创建一个通用的 DAO 类

在通用 DAO 中获取当前对象 ID。休眠