数据库和模型之间应该有一个抽象层吗?

时间:2013-12-04 18:51:01

标签: model-view-controller orm model repository-pattern

我看到很多是人们在MVC环境中工作时使用对象关系映射器(ORM)来执行SQL操作。但是,如果我真的有复杂的查询,我想自己写这整个查询。这种情况的最佳做法是什么?

  1. 使用复杂查询在模型和数据库之间建立抽象层
  2. 仍然使用模型创建处理查询的特定方法
  3. 或者还有其他方法可能更好吗?请告诉我:))

4 个答案:

答案 0 :(得分:2)

考虑Single Responsibility Principle。具体来说,问题是......

“如果我在我的模型中放入数据访问逻辑,那么当我需要更改内容时,这意味着什么?”

每当您需要更改业务逻辑时,您也会更改维护数据访问逻辑的对象。因此,数据访问逻辑也需要重新测试。相反,只要您需要更改数据访问逻辑,您也可以更改维护业务逻辑的对象。因此,业务逻辑也需要重新测试。

随着逻辑的扩展,这变得更加困难。

单一责任原则背后的理念是将不同角色的依赖关系分开,这些依赖关系可以对应用程序进行更改。 (请记住,“角色”不会与“人”一对一地映射。一个人可能有多个角色,但分离这些角色仍然很重要。)这是一个更简单的支持问题。如果您想对数据库查询进行更改(例如,出于性能原因),这些更改不会对系统中的任何其他内容产生任何明显影响,那么就没有理由更改包含业务逻辑的对象。

答案 1 :(得分:1)

  

1.在模型和具有复杂查询的数据库之间建立抽象层

是的,您应该在存储(数据库或任何其他数据源)和业务逻辑之间存在持久性抽象。您的业​​务逻辑不应该依赖于“where”,“how”甚至“if”数据实际存储。

基本上,您的代码应该(至少 - 尝试)遵守SOLID principles,但正如@david已经指出的那样:您已经违反了该列表中的第一个。

此外,您应该考虑使用service layer来负责处理域模型实现与持久性抽象之间的交互(无论您使用的是自定义编写的data mappers还是某些第三方ORM)。

在文章中(实际上更像是摘录),“MVC模型”实际上是三个同心圆。 Domain model不是代码。它实际上是trm,它描述了有关项目的累积知识。大多数域模型都变成了代码片段。这些作品被称为domain objects

  

2.仍在使用模型创建处理查询的特定方法

这意味着active record的实施。对于您的对象没有(或几乎没有)业务逻辑的情况,它很有用,但主要是误用模式。基本上 - 你应该使用活动记录 如果你需要的只是glorified setter get getters,那就是与数据库对话。

当您尝试实现完全实现的模型层时,当需要快速构建原型时,活动记录模式是一个非常好的选择,但不应该

答案 2 :(得分:0)

与使用直接SQL从数据库中获取数据相比,ORM通常没有任何缺点。 ORM的名称意味着帮助保持您的Relational模型(使用您的SQL DDL或使用JPA注释设计)和OO模型同步并帮助它们很好地集成在一起。

使用ORM时,您可以使用面向对象的SQL的JPQL编写查询。因此,您不是编写操纵表的查询,而是编写操纵对象的查询。您可以使用这些对象之间的关系来获得所需的结果。现在我明白,有时它更容易编写Native SQL,因此JPA规范允许您运行本机sql!这只会返回您可以按照自己喜欢的方式组织的“通用对象”列表。当你选择走这条路线并实际选择一个JPA提供商(如Hibernate)时,这些提供商已经扩展了功能。因此,如果您确实有复杂的关系,您可以使用Hibernate Criteria Builder等库来帮助您为这些复杂的关系创建查询。

因此,如果构建一个大型MVC应用程序,通常最好将这个抽象层放在中间 - 处理所有这些关系。它使开发人员更容易看到应用程序的全局和业务方面。

答案 3 :(得分:0)

Imho,不。我认为,即使是ORM层也会根据需要增加复杂性。数据库具有非常好的和复杂的高级数据操作机制。触发器,视图,约束,复杂的键控索引,(子)事务,存储过程和查询语言的过程扩展通常对于所有内容都足够了。

由于其结构障碍,ORM无法提供此功能集的真实界面。

通常的做法是应用程序实际上只使用所有这些的nosql记录服务,并在不需要的“中间件”中实现,这是数据库的任务。

我觉得非常有趣,如果数据库的功能集有一些类似OO的接口(参见“sql abstract types”),并且客户端逻辑进入了应用程序(参见“REST”)。这实际上消除了对中间层的需求。