4

我正在开发一个使用 Spring MVC 和 Hibernate 的 CRM 项目,但我不知道使用 hibernate 标准的最佳位置是什么。我想使用休眠条件,因为我们在表示层上具有搜索功能,用户可以根据许多不同的参数以不同的方式进行搜索。有时我们只需要 ID,有时我们需要属性的子集,有时我们需要连接多个表等。因此,构建一个结构化的标准,如 hibernate 的标准,而不是从表示中传递参数列表、顺序、所需参数和搜索限制层到数据层,可以清理代码。但是,我知道在表示层使用休眠是不正确的,因为它违反了 MVC 架构。而且我真的不认为复制hibernate的标准是正确的方法。我可以想到3种方法:

  1. 在业务层创建了十几个方法,每个类型的搜索请求一个,并根据情况从表示层调用这些函数中的每一个。这些方法中的每一个基本上,除了将参数传递给相应的 DAO 方法之外什么都不做,该方法将创建 SQL 查询(或标准对象)并从数据库中检索数据。在这种方法中,我最终会得到数百个方法,这些方法除了将参数传递给 DAO 之外什么都不做。

  2. 在表示(或业务层)中创建一个类似于 Hibernate 的 Criteria 类的类。然后在表现层用搜索参数初始化这个对象并将它传递给DAO。然后 DAO 基于这个对象创建一个休眠的条件对象。这种方法涉及复制hibernate的标准类。

  3. 在表现层启动 Hibernate 的 Criteria 类并将其传递给 DAO 以获取搜索结果。

你能告诉我哪个是最好的方法吗?

谢谢

4

3 回答 3

1

另一种选择是创建特定于查询的图层。这个概念来自 CQRS。我不使用 NHibernate,但我确实使用 ADO.NET 直接执行我的查询,因为我赞同不应查询域模型的想法。在这里和那里加载完整的聚合并没有错,但绝对不适用于临时查询。

因此,假设您可以ContactQuery使用以下方法:

  • public string Name(Guid contactId)
  • public DataRow Details(Guid contactId)
  • public DataTable CustomerContacts(Guid customerId)

这样,您的查询就被抽象了。希望 NHibernate 预测返回 DataRow / DataTable :)

于 2011-10-04T04:29:17.200 回答
1

我认为最佳选择取决于您的查询要求。

如果可能的话,我会建议你去第一个选择。我经常发现自己在实现采用大量可空参数的 DAO 搜索方法。如果相应的方法参数未设置为 NULL,则 DAO 方法本身会构建添加约束的条件对象。

这是一个简单的例子:

public List<SomeObject> findSomeObjects(String name, Integer categoryId, 
      Date dateTimeFrom, Date dateTimeUntil) {
   if (name != null)
     // add name to criteria
   if (categoryId != null)
     // add category to criteria
   // ...
}

如果确实有很多不同的搜索操作并且组合的数量非常多,您也可以尝试第二种选择。也许您可以通过为您的用例简化和定制它来限制您的标准“克隆”。

于 2011-10-04T02:10:39.920 回答
0

我会继续创建 Criteria 对象并将其传递到 DAO 层。原因有两个:

  1. 防止 DAO 中 finder 方法的自然爆炸
  2. 以避免代码重复(这是第二种选择所固有的)。

因此,您可以将标准对象视为垂直域层的一部分。

PS我不知道你的情况,但一个更好的选择可能是使用JPA 2 Criteria作为Hibernate Criteria的标准“替代品”,以避免在没有强烈必要性的情况下依赖Hibernate特定功能。

于 2011-11-23T16:31:05.450 回答