控制器,实体类或dao - 什么去哪里?

时间:2011-07-13 16:20:33

标签: java hibernate orm dao

随着Hibernate在我的项目中的引入,我的代码开始变得非常耦合,并且在许多地方都是样板(并且应该反过来,对吧?)

我对一个特定的例子感到非常困惑。我一直认为DAO对象本质上是非常通用的(主要是封装基本的CRUD操作以及后端存储实现)

不幸的是,随着我的实体类开始变得越来越复杂,我开始向DAO对象卸载越来越多的逻辑。我有一个特别的例子:

我的实体类用户应该有一个名为friends的关系,它本质上是一组用户。但是,我必须将我的类映射到UserFriendship对象的集合,每个对象都包含对friend对象的引用,以及其他特定的友谊数据(友谊发生的日期)

现在,很容易在实体类中引入自定义getter,它将获取UserFriendship对象的集合并将其转换为User对象的集合。但是,如果我只需要我的朋友集合的一部分,比如在分页中,该怎么办?我无法在实体对象中真正做到这一点,因为它无法访问会话,对吧?当我需要对关系进行参数化查询时,这也适用。可以访问会话的是UserDAO。所以我最终得到了这个

UserDAO的    =>正常的CRUD方法    => getFriends(整数偏移量,整数限制);    =>一群类似的getter和setter负责管理User实例中的关系。

这太疯狂了。但我真的不能做任何其他事情。我不知道是否可以在实体类中声明计算属性,也可以参数化。

我在技术上也可以将DAO包装在实体中,并将​​帮助器getter和setter放回到实体类中,它们应该在那里,但我不确定这是否也是一个好习惯。

我知道DAO只能由控制器对象访问,它应该提供一个或多或少完整的实体对象或一组实体对象。

我很困惑。或多或少,我的所有DAO对象现在都会耦合应该在Entity对象或控制器中的逻辑。

如果我的问题有点令人困惑,我很抱歉。制定它有点难。

1 个答案:

答案 0 :(得分:13)

我的一般规则是:

  • 在实体类中,尊重law of Demeter:不要与陌生人交谈
  • 实体类不得使用会话
  • 控制器/服务类不得使用会话。他们可以在实体图中导航并调用DAO方法
  • DAO方法应该是使用会话的方法。他们的工作包括获取,保存,合并实体和执行查询。如果应该为单个用例执行多个查询或与持久性相关的操作,则控制器/服务应该协调它们,而不是DAO。

这样,我可以通过模拟DAO来相对轻松地测试业务逻辑,并且我可以相对容易地测试DAO,因为它们不包含太多逻辑。大多数测试验证查询找到了他们应该找到的内容,以适当的顺序返回它们,并初始化必须初始化的关联(以避免在表示层中延迟加载异常,我在使用分离的对象)

相关问题