我正在使用spring mvc和hibernate实现一个企业应用程序。应用程序体系结构由以下层组成:
使用经典dao模式实现数据访问,并允许CRUD操作+通用查询。我应该在哪里实现特定查询?我猜两个解决方案:
我该怎么办?有更好的解决方案吗?
答案 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是&#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()
等基本方法
例如
public interface IClient extends IDao {
public void findWithWhere(String where);
}
public class ClientDaoImpl extends GenericDao<Client> implements IClient {
public void findWithWhere(String where) {
//do custom stuff here
}
}
然后在Controller(或服务)层中有一个ClientDaoImpl对象 这可能看起来有些累人,但是,对我来说,它保持所有层次分工,当我必须更改方法(可能接收新参数)时,我简单地更改界面以了解我必须实现的位置。