我正在开发一个使用Spring MVC和Hibernate的CRM项目,我不知道什么是使用hibernate标准的最佳位置。我想使用hibernate标准,因为我们在表示层上具有搜索功能,用户可以通过不同方式基于各种参数进行搜索。有时我们只需要ID,有时我们需要属性的子集,有时我们需要连接多个表,等等。因此,构建一个结构化的标准,如hibernate的标准,而不是从表示中传递参数,订单,所需参数和搜索限制的列表层到数据层,可以清理代码。但是,我知道在表示层使用hibernate是不正确的,因为它违反了MVC架构。我真的不认为重复hibernate的标准是正确的方法。我可以想到3种方法:
在业务层创建十二个方法,每种类型的搜索请求一个,并根据情况从表示层调用这些函数。这些方法中的每一种基本上都不做任何事情,只是将参数传递给相应的DAO方法,该方法将创建SQL查询(或条件对象)并从数据库中检索数据。在这种方法中,我最终会得到数百种方法,除了将参数传递给DAO之外什么都不做。
在演示文稿(或业务层)中创建类似于Hibernate的Criteria类的类。然后使用表示层中的搜索参数启动此对象并将其传递给DAO。然后,DAO基于此对象创建一个hibernate的条件对象。这种方法涉及复制hibernate的标准类。
在表示层启动Hibernate的Criteria类并将其传递给DAO以获取搜索结果。
你能告诉我哪一个是最好的方法吗?
由于
答案 0 :(得分: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
// ...
}
如果确实存在很多不同的搜索操作且组合数量非常高,您也可以尝试第二种方法。也许你可以通过简化和定制你的用例来限制你的Criteria“克隆”。
答案 1 :(得分:1)
另一种选择是创建特定于查询的图层。这个概念来自CQRS。我不使用NHibernate,但我确实使用ADO.NET直接执行我的查询,因为我订阅了不应该查询域模型的想法。在这里加载完整聚合没有错,但是对于临时查询肯定不是。
因此,假设您可以使用以下方法获得ContactQuery
之类的内容:
public string Name(Guid contactId)
public DataRow Details(Guid contactId)
public DataTable CustomerContacts(Guid customerId)
通过这种方式,您的查询被抽象化了。希望NHibernate投影返回DataRow / DataTable:)
答案 2 :(得分:0)
我会创建并将Criteria对象向前传递到DAO层。原因有两个:
因此,您可以将标准对象视为垂直域图层的一部分。
P.S。我不知道你的情况,但稍微好一点的选择可能是使用JPA 2 Criteria作为Hibernate Criteria的标准“替代”,以避免依赖Hibernate特定的功能而没有强烈的必要性。