简体   繁体   English

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

[英]Where should I implement specific queries in mvc architecture(spring + hibernate)?

I'm implementing an enterprise application using spring mvc and hibernate. 我正在使用spring mvc和hibernate实现一个企业应用程序。 The application architecture is composed by the following layers: 应用程序体系结构由以下层组成:

  • View 视图
  • Controller 调节器
  • Service 服务
  • Domain
  • Peristence Peristence

The data access is implemented with classic dao pattern and allows CRUD operations + generic queries. 数据访问使用经典dao模式实现,并允许CRUD操作+通用查询。 Where should I implement specific queries? 我应该在哪里实现特定查询? I guess two solutions: 我想两个解决方案:

  • implement specific queries in the service layer by creating hibernate criteria and passing it to the persistence layer 通过创建hibernate标准并将其传递给持久层,在服务层中实现特定查询
  • implement specific queries in DAO classes by create a function for each query and call the functions in the service layer. 通过为每个查询创建一个函数并在服务层中调用函数,在DAO类中实现特定查询。

What should I do? 我该怎么办? Are there better solutions? 有更好的解决方案吗?

Service layer is a business layer and there must not be used any persistence provider related interfaces and classes (ie Hibernate Criteria API). 服务层是业务层不得使用任何与持久性提供程序相关的接口和类(即Hibernate Criteria API)。 That's a good practice - you can change your persistence provider without touching any line of code in your service layer. 这是一个很好的做法 - 您可以更改持久性提供程序,而无需触及服务层中的任何代码行。

Don't hesitate to go with your second option (implement specific queries in DAO classes). 不要犹豫,使用第二个选项(在DAO类中实现特定查询)。

Alternatively you can use kind of business dynamic query pattern which is mix of the query and builder pattern (like Criteria API). 或者,您可以使用一种业务动态查询模式,它是查询构建器模式的混合(如Criteria API)。 Here is the simple example: 这是一个简单的例子:

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

You can implement HibernateCarQuery that can use Hibernate Criteria API internally. 您可以实现HibernateCarQuery可以在内部使用Hibernate API标准。 This surely requires some additional efforts but will not pollute your daos with specific methods if you're planning to use them extensively and need ability to build queries dynamically (typical case is multiple filters on UI pages). 这肯定需要一些额外的努力,但如果您计划广泛使用它们并且需要能够动态构建查询(典型情况是UI页面上的多个过滤器),则不会使用特定方法污染您的daos。

From layered architecture perspective, the sql queries should not be used/declared outside DAO layer. 从分层体系结构的角度来看,不应在DAO层之外使用/声明sql查询。 You might have noticed that spring opted to use transaction on service layer since transaction is not the responsibility of DAO and you can also call it as resource leakage/cross cutting concern. 您可能已经注意到spring选择在服务层上使用事务,因为事务不是DAO的责任,您也可以将其称为资源泄漏/交叉问题。 Declaring /using sql queries apart from Dao will be considered to be resource leakage/cross cutting concern. 声明/使用除Dao之外的sql查询将被视为资源泄漏/交叉问题。

I would like to add something since you touched hibernate and criteria API. 我想添加一些东西,因为你触及了hibernate和标准API。 When you are using criteria then why should you need separate query? 当您使用标准时,为什么还需要单独的查询? Criteria API is an elegant way to achieve persistence because it is perfect OO approach. Criteria API是一种实现持久性的优雅方式,因为它是完美的OO方法。

This: 这个:

  • implement specific queries in DAO classes by create a function for each query and call the functions in the service layer. 通过为每个查询创建一个函数并在服务层中调用函数,在DAO类中实现特定查询。

DAO is shorthand for "Data Access Object" and one of the maim reasons to use the DAO pattern is to comply with the "Single Responsibility Principle". DAO是“数据访问对象”的简写,使用DAO模式的一个主要原因是遵守“单一责任原则”。 If you have some other classes in your code, other than the DAO classes, which handle Data Access, then you are violating the SRP and it becomes a more or less moot point to use the DAO pattern at all. 如果您的代码中有一些其他类,除了处理数据访问的DAO类,那么您违反了SRP,并且根本就没有使用DAO模式。

More importantly, for maintainability purposes, if other developers are going to maintain your code later on, and they see a bunch of DAO classes lying about, they are not going to expect data access to be happening anywhere else. 更重要的是,出于可维护性的目的,如果其他开发人员稍后要维护您的代码,并且他们看到一堆DAO类,那么他们就不会期望在其他地方发生数据访问。

Your service layer isn't even supposed to have a dependency on Hibernate. 您的服务层甚至不应该依赖于Hibernate。 Why would you have that? 你为什么要这样? Your service layer should only depend on your domain layer, which in turn depends on your persistence layer, which is where your Hibernate dependency should be, 您的服务层应该只依赖于您的域层,而域层又取决于您的持久层,这是您的Hibernate依赖项所在的位置,

It is better to have all the queries in the DAO class methods and run them. 最好在DAO类方法中包含所有查询并运行它们。 If you are working on HQL, have all the queries written in the NamedQuery and access it by name at the run time. 如果您正在使用HQL,请在NamedQuery中编写所有查询,并在运行时按名称访问它。

I use to create a GenericDAO class and an IDao interface and all the other DAOs - let's say a ClientDAO - extends the Generic. 我用来创建一个GenericDAO类和一个IDao接口以及所有其他DAO - 假设一个ClientDAO - 扩展了Generic。


That being said, I create an interface that extends IDao (which have the basics methods like findAll() , delete() , save() ) 话虽这么说,我创建了一个扩展IDao的接口(其中包含基本方法,如findAll()delete()save()


Eg 例如

IClient IClient

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

ClientDaoImpl ClientDaoImpl

public class ClientDaoImpl extends GenericDao<Client> implements IClient {

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

And then have a ClientDaoImpl object in the Controller (or Service) Layer 然后在Controller(或服务)层中有一个ClientDaoImpl对象
That may look a little tiring to do, but, for me, it keeps all the layers well divided and when I have to change a method (maybe receive a new parameter), I simple change the interface to know where I have to implement. 这可能看起来有些累人,但是,对我来说,它保持所有层次分工,当我必须更改方法(可能接收新参数)时,我简单地更改界面以了解我必须实现的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Spring MVC Hibernate应用程序中,应该将用户图像保存在哪里? - In a Spring MVC Hibernate application, where should I save user images? 我应该在Maven项目的n层体系结构中将Spring MVC配置类编写在哪里? - Where should I write my Spring MVC configuration class in a n-tiers architecture in a Maven project? 如何添加到JPA 2 Criteria查询的Spring / Hibernate体系结构创建中? - How to add to Spring/Hibernate architecture creation of JPA 2 Criteria queries? 我应该在Spring MVC项目中的何处放置bean定义? - Where should I put the bean definition in Spring MVC project? 我应该为此特定方法创建2个单元测试吗? Spring MVC应用 - Should I create 2 unit tests for this specific method? Spring MVC app Spring MVC和Hibernate应该按需保存事务 - spring mvc and hibernate should save the transaction on demand 在可能的情况下,是否应该删除SQL查询以支持使用Hibernate? - Where possible, should SQL queries be eliminated in favour of utilising Hibernate? 我应该在这种多线程体系结构中使用Hibernate还是放弃它? - Should I use Hibernate with this multi-threaded architecture or abandon it? 我应该如何在 Kafka 中实现延迟主题架构 - How should I implement delayed topic architecture in Kafka Spring MVC插件架构 - Spring MVC Plugin Architecture
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM