通用DAO - “永远不会完全通用!”

时间:2013-05-18 21:53:53

标签: spring hibernate dao hibernate-generic-dao

我已经在互联网上看到了通用dao的所有用法。 你必须喜欢它:

public interface GenericDao <T, PK extends Serializable> {}

public class GenericDaoHibernateImpl <T, PK extends Serializable>
implements GenericDao<T, PK>

出现了一个新班级?没问题:

public interface NewClassDao extends GenericDao<NewClass, Long> 

我们都准备好了。

现在, 如果我去“完全通用”并做类似的事情有多糟糕:

public interface FullGenericDao 

public class FullGenericDaoHibernateImpl

现在我只能使用一个DAO(带有强制转换的对象!)

又出现了一个新班级? 没问题:

NewClassApperedAgain newClassAppeared = (NewClassApperedAgain) FullGenericDao.getItemById(20, NewClassApperedAgain.class);
脑海中浮现出两个问题:

1)甚至可以“完全通用”并实际创建这样的DAO吗?我的意思是我不明白为什么不传递dao的每个方法className,只是做必要的铸造? 保存(对象,类名); 删除(对象,类名);等。

2)这种做法有什么缺点(我确定有)?

谢谢!

1 个答案:

答案 0 :(得分:1)

DAO对象包含与持久层相关的域模型特定逻辑。

您可以使用完整通用,但之后您必须面对以下问题:

  • 我应该把逻辑与搜索联系起来(例如构建WHERE子句)?
    • User findUserByOrganizationId(Serializable organizationId)
  • 我在哪里放置一些特定的映射函数(例如聚合查询)?
    • Map<Organization, Integer> findUserCountPerOrganization()

我很确定还有其他架构/逻辑问题。此外,泛型将在运行时删除,因此您已经介绍了在每个方法签名中包含域对象Class<?>的必要性。

TL; DR 可以“完全通用”,但您需要将非共享持久性逻辑移动到更高级别。最好在某些AbstractDaoImpl中执行共享通用逻辑,然后再将其子类化。您最终可能会得到空的实现(通用超类可能只需要您所需的一部分),但您可以使用未来的域模型特定方法。