带有休眠的 DAO 和服务层

Posted

技术标签:

【中文标题】带有休眠的 DAO 和服务层【英文标题】:DAO and Service Layer with hibernate 【发布时间】:2011-05-01 04:38:36 【问题描述】:

我在实现服务层时遇到了麻烦,我想我不太了解这个概念。

在 DAO 实现中,我可以为特定技术和实体(例如休眠和用户表)编写所有 CRUD 逻辑,而在服务层中,我们使用 DAO 对 DAO 中的实体进行所有数据操作(如 getUser、 loginUser 等)这样可以吗?

如果没问题,我有一个简单的问题,我可以在服务层、DAO 实现中处理数据库连接(或者在休眠、会话和事务的情况下)吗?

例如,我有一个带有一个按钮的简单 GUI(加载所有用户),并且一个表将包含所有用户。按下按钮将加载所有用户的表格。

我有一个用于用户实体的 HibernateDAO (UserHibernateDAO),其中包含所有 CRUD 操作和一个服务层 UserService,用于与用户进行一些特定的数据操作。

服务层:

public class UserService extends AbstractServiceLayer

    private AbstractDAO dao;

    public UserService(AbstractDAO dao)
     this.dao=dao;
    

    public List<User> loadAllUsers()
     return dao.findAll();
    


在按钮的执行中:

private void buttonActionPerformed(ActionEvent evt) 
    Transaction transaction=HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
    List<User> users=userService.loadAllUsers();
    loadTableWithUsers(users);
    transaction.commit();

这个实现好吗? 会话和事务句柄处于正确位置还是我必须将其放入服务层? ..或者也许进入道?

EDIT1:

如果我有一个接口 UserDAO 和一个实现 UserDAO 的 UserHibernateDAO,服务层就没有理由存在,不是吗? 因为我可以拥有所有方法来管理我的 UserDAO 中的“用户”,而 UserHibernateDAO 实现了所有这些用于休眠技术的方法......然后我可以拥有 UserJdbcDAO、UsermysqlDAO 等......嗯......

EDIT2:

private void buttonActionPerformed(ActionEvent evt) 
    myBusinessMethod();


private void myBusinessMethod()
    Transaction transaction=HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
    List<User> users=userService.loadAllUsers();
    loadTableWithUsers(users);
    //some other useful operation before close session
    transaction.commit();

我不确定,业务方法是这样的方法吗?

谢谢大家。

【问题讨论】:

我想,我已经回答了你的edit :)。请参阅我的第二个建议。 【参考方案1】:
    您正在actionPerformed() 方法中处理事务。它显然违背了 DAO/Service 层的目的 您的 UserService 正在接受 AbstractDAO,这意味着其他一些代码可能会将错误的 DAO 实现传递给您的 UserService,这会搞砸

现在,一些建议。

    您可以为此查看GenericDAO concept。这可能适合您的需要 大多数时候,我们不需要像ServiceDAOBusinessDelegate 这样的所有这些层。所以,问问你自己是不是真的回答了你的一些问题。如果没有,请摆脱它们。 YAGNI 彻底摆脱 DAO,将您的 Hibernate API 视为您的 DAO。在您的业务方法中处理数据库事务。你可能想读这个question

[已编辑]

在您编辑后,我的第三条建议没有多大意义。顺便说一句,你将你的 DAO 命名如下: UserJdbcDAOUserMysqlDAO 等。您的第二个名字没有多大意义,因为我们使用 ORM 只是为了避免数据库供应商特定的 DAO/查询。如果你的 UserMysqlDAO extends UserJdbcDAO 可能会开始有意义。

【讨论】:

@Adeel Ansari: 1- 我在哪里可以处理交易? 2-为什么这是不正确的?具体数据操作进入服务层。 @blow:您可以在您的 DAO 或业务方法中处理它。我通常更喜欢在我的业务方法中这样做。 @Adeel Ansari:现在我的 genericDao 是这样的community.jboss.org/wiki/GenericDataAccessObjects 但我还没有实现 DaoFactory。你能写一个简单的例子来告诉我如何以及在哪里处理会话和事务吗?我想不明白业务逻辑是什么意思。 @blow:哦,好吧。现在,当您保留 DAO 时,可以在 DAO 方法中管理事务。也许,当您在调用代码中需要加载一些配置为fetch-lazy 的关联时,您会遇到的唯一问题。为什么,因为您的会话已经关闭,您可以访问数据库。 @blow:是的,很可能是同一个会话。但它看起来不是很整洁。现在第二个问题,是的,可以说是一种商业方法,准确地说。

以上是关于带有休眠的 DAO 和服务层的主要内容,如果未能解决你的问题,请参考以下文章

不使用休眠模板的服务方法

在DAO,服务层架构中使用spring MVC和Hibernate的正确方法是啥

取消引用的休眠 (JPA) 实体会发生啥情况?

域、DAO 和服务层

创建服务层和DAO层(接口+实现)或仅实现

JPA 和 EJB 以及分离的 DAO 和服务层