在MVC架构中我应该在哪里使用Hibernate标准?

在MVC架构中我应该在哪里使用Hibernate标准?,hibernate,model-view-controller,search,hibernate-criteria,Hibernate,Model View Controller,Search,Hibernate Criteria,我正在从事一个使用SpringMVC和Hibernate的CRM项目,我不知道使用Hibernate标准的最佳位置是什么。我想使用hibernate标准,因为我们在表示层上有搜索功能,用户可以基于许多不同的参数以不同的方式进行搜索。有时我们只需要ID,有时我们需要属性的子集,有时我们需要连接多个表,等等。因此,构建一个结构化的标准,如hibernate的标准,而不是将参数列表、顺序、所需参数和搜索限制从表示层传递到数据层,可以清理代码。然而,我知道在表示层中使用hibernate是不正确的,因为

我正在从事一个使用SpringMVC和Hibernate的CRM项目,我不知道使用Hibernate标准的最佳位置是什么。我想使用hibernate标准,因为我们在表示层上有搜索功能,用户可以基于许多不同的参数以不同的方式进行搜索。有时我们只需要ID,有时我们需要属性的子集,有时我们需要连接多个表,等等。因此,构建一个结构化的标准,如hibernate的标准,而不是将参数列表、顺序、所需参数和搜索限制从表示层传递到数据层,可以清理代码。然而,我知道在表示层中使用hibernate是不正确的,因为它与MVC体系结构相反。我真的不认为复制hibernate的标准是正确的方法。我可以想到三种方法:

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

  • 在表示层(或业务层)中创建一个类似于Hibernate的Criteria类的类。然后使用表示层中的搜索参数启动该对象,并将其传递给DAO。DAO然后基于此对象创建hibernate的criteria对象。这种方法涉及复制hibernate的criteria类

  • 在表示层启动Hibernate的Criteria类并将其传递给DAO以获得搜索结果

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


    谢谢

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

    如果可能的话,我建议你选择第一种选择。我经常发现自己实现的DAO搜索方法需要很多可为空的参数。如果相应的方法参数未设置为NULL,DAO方法本身将通过添加约束来构建criteria对象

    这是一个简单的例子:

    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
       // ...
    }
    
    public List findSomeObjects(字符串名称、整数类别ID、,
    Date dateTimeFrom,Date dateTimeUntil){
    if(name!=null)
    //将名称添加到条件中
    if(categoryId!=null)
    //将类别添加到标准
    // ...
    }
    

    如果确实有很多不同的搜索操作,并且组合的数量非常多,那么您也可以尝试第二种选择。也许您可以通过简化并根据您的用例对其进行裁剪来限制条件“克隆”。

    另一个选项是创建查询特定的层。这个概念来自CQR。我不使用NHibernate,但我使用ADO.NET直接执行查询,因为我同意不应该查询域模型的想法。到处加载一个完整的聚合并没有什么错,但对于临时查询肯定没有错

    因此,假设您可以使用类似于
    ContactQuery
    的方法,例如:

    • 公共字符串名称(Guid联系人ID)
    • 公共数据行详细信息(Guid联系人ID)
    • 公共数据表CustomerContacts(Guid customerId)

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

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

  • 防止DAOs中探测器方法的自然爆炸
  • 避免代码重复(这是第二个选项固有的)
  • 因此,您可以将标准对象视为垂直域层的一部分


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

    感谢Matthias的回答。第一种方法是我去年开始做的,我在DAO中使用了很多大型复杂的方法,因为除了大量的搜索参数之外,我们还需要各种表连接和投影(需要加载哪些列的限制)。因此,过了一段时间,我选择了第二种方法,构建了自己的Criteria类,并开始扩展它,复制了hibernate的大部分Criteria功能。所以,我想知道什么是常见的方法。也许在表示层使用Hibernate的标准不是一个坏主意。