我应该在mvc架构中实现特定的查询(spring + hibernate)?

时间:2014-01-03 16:52:06

标签: java spring hibernate spring-mvc

我正在使用spring mvc和hibernate实现一个企业应用程序。应用程序体系结构由以下层组成:

  • 查看
  • 控制器
  • 服务
  • Peristence

使用经典dao模式实现数据访问,并允许CRUD操作+通用查询。我应该在哪里实现特定查询?我猜两个解决方案:

  • 通过创建hibernate标准并将其传递给持久层
  • ,在服务层中实现特定查询
  • 通过为每个查询创建一个函数并在服务层中调用函数,在DAO类中实现特定查询。

我该怎么办?有更好的解决方案吗?

5 个答案:

答案 0 :(得分:3)

服务层是业务层不得使用任何与持久性提供程序相关的接口和类(即Hibernate Criteria API)。这是一个很好的做法 - 您可以更改持久性提供程序,而无需触及服务层中的任何代码行。

请继续使用您的第二个选项(在DAO类中实现特定查询)。

或者,您可以使用业务动态查询模式,它是查询构建器模式(如Criteria API)的混合模式。这是一个简单的例子:

interface CarQuery {
    CarQuery model(String model);
    CarQuery color(String color);
    List<CarQuery> execute(); 
}
....
List<Car> cars = carDao.getQuery().model("Jeep").color("green").execute();
....

您可以在内部实现可以使用Hibernate Criteria API的 HibernateCarQuery 。这肯定需要一些额外的努力,但如果您计划广泛使用它们并且需要能够动态构建查询(通常情况下是UI页面上的多个过滤器),则不会使用特定方法污染您的daos。

答案 1 :(得分:1)

从分层架构的角度来看,不应在DAO层之外使用/声明sql查询。您可能已经注意到spring选择在服务层上使用事务,因为事务不是DAO的责任,您也可以将其称为资源泄漏/交叉问题。声明/使用除Dao之外的sql查询将被视为资源泄漏/交叉问题。

我想添加一些东西,因为你触及了hibernate和标准API。当您使用标准时,为什么还需要单独的查询? Criteria API是实现持久性的一种优雅方式,因为它是完美的面向对象方法。

答案 2 :(得分:1)

此:

  • 通过为每个查询创建一个函数并在服务层中调用函数,在DAO类中实现特定查询。

DAO是&#34;数据访问对象&#34;的简写。使用DAO模式的一个主要原因是遵守&#34;单一责任原则&#34;。如果你的代码中有一些其他类,除了处理数据访问的DAO类,那么你违反了SRP,根本就没有使用DAO模式。

更重要的是,出于可维护性的目的,如果其他开发人员稍后要维护您的代码,并且他们看到了大量的DAO类,他们就不会期望在其他地方发生数据访问。

您的服务层甚至不应该依赖于Hibernate。你为什么要这样?您的服务层应该只依赖于您的域层,而域层又依赖于您的Hibernate依赖所在的持久层,

答案 3 :(得分:0)

最好在DAO类方法中包含所有查询并运行它们。如果您正在使用HQL,请在NamedQuery中编写所有查询,并在运行时按名称访问它。

答案 4 :(得分:0)

我用来创建一个GenericDAO类和一个IDao接口以及所有其他DAO - 让我们说一个 ClientDAO - 扩展了Generic。

左说,我创建了一个扩展IDao的界面(其中包含findAll()delete()save()等基本方法


例如

IClient

public interface IClient extends IDao { 
   public void findWithWhere(String where);
}

ClientDaoImpl

public class ClientDaoImpl extends GenericDao<Client> implements IClient {

  public void findWithWhere(String where) {
   //do custom stuff here
  }
}

然后在Controller(或服务)层中有一个ClientDaoImpl对象 这可能看起来有些累人,但是,对我来说,它保持所有层次分工,当我必须更改方法(可能接收新参数)时,我简单地更改界面以了解我必须实现的位置。