已关闭。此问题为opinion-based。当前不接受答案。
**想要改进此问题吗?**请更新此问题,以便editing this post可以用事实和引文来回答。
九年前就关门了。
Improve this question
我在一些文章中读到DAO并不是Hibernate所必需的,它的实现是通过“它依赖于”,换句话说,我们可以在ORM和DAO模式之间进行选择。
好,假设我不想使用DAO模式,所以我只使用Hibernate(我的ORM)提供的会话CRUD和查询操作。
特别是对于“search”和“find”查询总是不正确地重写它们,所以合理的想法是把它们放到一个类中。
但是这个类是一个简单的DAO,没有DAO模式和DAOFactory的所有实现,只有一个DAO的轻量级实现,那么,关键是我们总是需要一个DAO,是选择重型DAO实现还是轻量级DAO实现?
我说错了吗?
EDIT我的另一个问题是把dao交互放在哪里,例如我必须登录一个用户并写一个登录日志(我知道这个例子很没用...)
所以在DAO模式中,我有所有的泛型dao实现,一个DAOFactory,最后是UserHibernateDAO和LogHibernateDAO。登录操作是一个业务方法:
private void login(String username, String password){
daoFactory.beginTransaction();
UserDAO userDao=daoFactory.HIBERNATE.getUserDao();
LogDAO logDao=daoFactory.HIBERNATE.getLogDao();
if(userDao.checkAccount(username, password){
User user=userDao.findByAccount(username, password);
logDao.save(new Log("log-in", user);
}
daoFactory.commit();
}
这合理吗?我可以这样使用dao吗?如果我想处理异常,最好是在业务逻辑中处理。
EDIT 2让我们假设使用DAO模式,这样做的主要原因是能够在技术之间切换(ORM-〉JDBC等),一切都很好,但是我在哪里可以处理Hibernate会话和事务呢?我不能把它放在DAO中,这是一个很大的模式,我不能把它放在服务层中,因为在一个hipohtecal交换机中,我必须删除所有这些事务(因为其他技术可能不使用它们)。
3条答案
按热度按时间gblwokeq1#
ORM和DAO是两个相互垂直的概念。一个是关于对象如何Map到数据库表,另一个是用于编写访问数据的对象的设计模式。你不能在它们之间做出选择。你可以将ORM和DAO作为同一个应用程序,就像你不需要ORM来使用DAO模式一样。
也就是说,虽然你从来没有真正"需要"任何东西,但你应该使用DAO。这种模式适合于模块化代码。你把所有的持久性逻辑放在一个地方(分离关注点,对抗泄漏的抽象)。你允许自己独立于应用程序的其余部分测试数据访问。你允许自己独立于数据访问测试应用程序的其余部分(也就是说,你可以模拟你的DAO)。
另外,即使实现数据访问可能很困难,遵循DAO模式也很容易,因此成本很低(或者没有成本),但收益很大。
使用该模式的主要原因是分离关注点。这意味着您所有的持久性代码都在一个地方。这样做的副作用是可测试性和可维护性,而且事实上这使得以后切换实现更容易。如果您正在构建基于Hibernate的DAO,您完全可以在DAO中操作会话。这就是你应该做的。2反模式是当持久化相关的代码发生在持久化层之外的时候(泄漏抽象法则)。
事务有点棘手。乍一看,事务似乎是持久性的一个问题,事实也确实如此。但它们不仅仅是持久性的一个问题。事务也是你的服务的一个问题,因为你的服务方法应该定义一个"工作单元",这意味着,在一个服务方法中发生的每件事都应该是原子的。如果你使用Hibernate事务,那么你将不得不在你的DAO之外编写休眠事务代码,来定义使用许多DAO方法的服务周围的事务边界。
但是要注意,事务可以独立于您的实现--无论您是否使用Hibernate,您都需要事务。还要注意,您不需要使用Hibernate事务机制--您可以使用基于容器的事务、JTA事务等。
毫无疑问,如果你不使用Spring或类似的东西,事务将是一个痛苦。我强烈推荐使用Spring来管理你的事务,或者EJB规范,我相信你可以用注解来定义你的服务周围的事务。
查看以下链接,了解基于容器的事务。
Container-Managed Transactions
Sessions And Transactions
我从中得到的结论是,您可以很容易地在服务级别定义DAO之外的事务,并且不需要编写任何事务代码。
另一个(不太优雅的)选择是将所有原子工作单元放在DAO中。你可以使用CRUD DAO来执行简单的操作,然后使用更复杂的DAO来执行多个CRUD操作。这样,你的编程事务就留在DAO中,你的服务将调用更复杂的DAO,而不必担心事务。
下面的链接是DAO模式如何帮助您简化代码的一个很好的示例
AO与ORM(休眠)模式
(谢谢)
请注意接口的定义是如何使业务逻辑只关心UserDao的行为,而不关心实现的。您可以使用hib或JDBC编写DAO。因此,您可以更改数据访问实现,而不会影响程序的其余部分。
toe950272#
让我提供一个源代码的例子,以hvgotcodes很好的答案:
因此,如前所述,DAO是一种最小化应用程序和后端之间耦合的设计模式,而ORM处理如何将对象Map到对象关系数据库(这减少了数据库和应用程序之间的耦合,但最终,如果不使用DAO,应用程序将依赖于所使用的ORM或更高级别的标准,如JPA)。
因此,如果没有DAO,更改应用程序将非常困难(例如,迁移到NoSQL数据库,而不是JPA兼容的ORM)。
raogr8fs3#
不,我不认为这是正确的。ORM是实现DAO的一种方式;您可以选择不使用ORM来执行DAO。
你说反了:我认为ORM比DAO重,因为依赖性更大。我可以直接用JDBC编写DAO而不用ORM。这样更轻,IMO。
我们是否同意取决于我们如何定义“轻”和“重”,我将根据依赖性--JDK本身之外所需的额外JAR的数量来定义。