• 原文出处:http://symfony.com/doc/current/book/doctrine.html
  • 原文作者:Symfony.com
  • 授权许可:创作共用协议
  • 翻译人员:FireHare <ubuntu.firehare AT gmail.com>
  • 校对人员:FireHare
  • 适用版本:Symfony 2
  • 文章状态:已校对

如果你想学习模型和超级模型的最新技术,本章将无法对你有所帮助。但如果你仅仅只是想学习一个模型,你应用程序中元数据的层,那么请阅读本章内容。本章所描述的模型用于构建MVC应用程序。

MVC(模型-视图-控制)最初由Trygve Reenskaug在Smalltalk平台上提出的应用程序设计模式。MVC的主要思路就是将展示从数据中分离出来,把控制器从展示中分离出来。这种分离让应用程序的各个部分都只关注一个目标。控制器关注模型数据的改变,模型将其数据向视图开放,而视图则关注创建模型的展示(如HTML页面展示博客博文)。

举个例子,当用户访问你博客首页时,用户的浏览器发送一个请求,该请求被发给控制器要求渲染博文列表。控制器计算要显示的博文列表,从数据库检索Post模型,并将Post数组发送给视图,视图渲染HTML以便在浏览器中显示。

到底什么是模型

模型在MVC中用M表示。它是MVC应用程序中三大部件之一。模型负责根据来自控制器的请求改变其内部状态,并将其当前状态信息传递给视图。它是应用程序主逻辑容器。

举个例子,如果你正在构建一个博客,那么你将拥有一个Post模型。如果你正在构建一个内容管理系统,那么你需要一个Page模型。

  1. <?php
  2. namespace Blog;
  3. class Post
  4. {
  5. private $title;
  6. private $body;
  7. private $createdAt;
  8. private $updatedAt;
  9. public function __construct($title, $body)
  10. {
  11. $this->title     = $title;
  12. $this->body      = $body;
  13. $this->createdAt = new \DateTime();
  14. }
  15. public function setTitle($title)
  16. {
  17. $this->title     = $title;
  18. $this->updatedAt = new \DateTime();
  19. }
  20. public function setBody($body)
  21. {
  22. $this->body      = $body;
  23. $this->updatedAt = new \DateTime();
  24. }
  25. public function getTitle()
  26. {
  27. return $this->title;
  28. }
  29. public function getBody()
  30. {
  31. return $this->body;
  32. }
  33. }

很明显,上述类非常简单也易于测试,除了一个简单的博客引擎外它几乎完成了一切。

就是这样,现在你知道在Symfony2中模型是什么:它是你想将其保存在某种顺序数据存储机制中并随后可以检索的类。本章节的其它部分将专门讲述它是怎么与数据库交互的。

数据库和Symfony2

Symfony2自己并没有实现ORM(对象关系映射)或DBAL(数据库抽象层),Symfony2要解决它并没有什么问题,但这没有任何意义。Symfony2提供了与类似Doctrine或Propel这样库的深度集成,这些库提供了ORM和DBAL包,可以让你使用你最喜欢的库。

ORM是对象关系映射的缩写,它代表一种在不兼容类型系统之间转换数据的编程技术。我们有一个Post,它被做为一条记录被保存在数据库里,但在应用程序中它又要做为Post类的一个实例来展现。将数据库的数据表转换成对象称之为对象关系映射。我们将发现这个术语有点过时,因为它只能在处理关系性数据库时使用。现在存在着大量的非关系性数据存储机制,有一种面向文档的数据库(如MongoDB),它所使用的术语是ODM(对象文档映射)。

接下来,你将学习关于Doctrine2 ORM和Doctrine2 ModgoDB ODM(为当下流行的文档存储:MongoDB所提供的ODM服务),这两者与Symfony2有着最深层次的集成。

模型不是数据表

模型类感觉就象是数据库的数据表,每个对象实例表示单个记录,这样的概念随着Ruby on Rails框架和Active Record设计模式的流行而广为人知。在应用程序模型层设计之初这样考虑是很好的,特别是在你正为修改模型数据而提供简单的CRUD(增删改查)时。

但这种想法其实会引起一个问题,一旦你完成应用程序的增删改查而要去添加更多的业务逻辑时,上述想法会引发 下面的限制:

  1. 在软件实际使用前先设计一个模式,就好象在知道你要埋什么之前先挖个坑。可能你埋的东西正好适合你所挖的洞,但如果你要埋辆大型的消防车呢?要想有效工作的话,你需要完全不同的思路;
  2. 数据库针对性地去适应你应用程序的需要,而不是反过来;
  3. 有些数据存储引擎(如文档数据库)并没有数据表、记录甚至是模式的概念,如果你认为模型就是数据表的话,你将很难使用它;
  4. 在你设计应用程序域的时候脑海中浮现的却是数据库模式,那么接下来在两者之间的最小公约数原则会让你焦头烂额的。

想象一起,脑子里想着数据库的结构,然后集中注意力去编写干净的模型以满足你业务需求是多么地痛苦,好在Doctrine2 ORM已经解决了这个问题。在要求你去考虑如何持久化数据之前,它会先让你设计你的类和相关的交互。

范式转换

随着Doctrine2的介绍,一些核心范式被转换。领域驱动设计(DDD)告诉我们对象是对真实世界原型建模的最好模型。例如Car对象是最好地建模,它包含Engine、4个Tire实例等,并且应该被CarFactory(知道如何将部件组装起来)生产出来。领域驱动设计本身就可以写一本书,因为它相当广泛。然而,考虑到本章的目的,我们需要知道的是汽车自己是无法启动的,它需要一个外部作用来启动它。与此相似,模型没有外部作用也是无法保存自己的,因此下面这段代码违反了DDD,并为重新设计一个干净、易测代码带来麻烦 。

  1. $post->save();

Doctrine2并不是传统的Active Record的实现。Doctrine2使用一个不同的模式集,几乎完全实现了Data Mapper和 Unit Of Work模式,下面是如何使用Doctrine2来保存实体的示例:

  1. $manager = //... 得到对象管理器实例
  2. $manager->persist($post);
  3. $manager->flush();

“对象管理器”是Doctrine提供的核心对象,它的作用是持久化对象。你不久将学到这个对象的更多内容。这个范式转换让我们摆脱了所有的基类(如Post不需要继承基类)和静态依赖。任何对象都可以保存到数据库并随后进行检索。更有甚者,一旦被持久化,该对象就可以通过对象管理器进行管理,直到管理器明确进行清理。这意味着所有对象的交互都发生在内存,直到调用$manager->flush()方法才发往数据库。不用说与大多数其它对象持久化模式相比,这个机制提供了一个即时数据库和优化查询,因为持久化尽可能地“懒”(它们的执行总是延迟到最后一刻)。

Active Record模式最重要的方面就是性能,或者说,构建一个高性能的系统是困难的。通过使用事务和内存对象改变跟踪,Doctrine2最大限度地减少与数据库的通信,从而节省数据库执行时间和昂贵的网络通信。

结论

感谢Doctrine2,使得Symfony2的模型现在也许已经是最简单的概念:它置于你的完全控制之下,而且不会受到持久化细节的限制。

通过与Doctrine2联合,你可以对你在持久化细节方面的代码感到放心,Symfony2使构建数据库方面的应用程序变得十分简单。应用程序代码保持干净,这将缩短开发时间并提高代码的可读性。

Symfony2Book04:Doctrine01-介绍模型(Model)相关推荐

  1. 【教程】利用libsvm-mat建立分类模型model参数解密【by faruto】

    原文地址:http://www.matlabsky.com/thread-12649-1-1.html 建议大家看这篇帖子之前先看一下以下几篇帖子: 如何使用libsvm进行分类[by faruto] ...

  2. php中orm模型,模型model

    ## 模型model 在看模型之前,我们先看一段yaf作者鸟哥在他自己博客里的一段文字吧: > 还有不少同学问, 为什么Yaf没有ORM, 这里有俩方面的考虑: 首先, Yaf并不是万能的, 它 ...

  3. python3.9 执行python3.6生成的随机森林模型model.pkl报错,警告版本不一致

    python3.9 执行python3.6生成的随机森林模型model.pkl报错 UserWarning: Trying to unpickle estimator RandomForestClas ...

  4. OpenGL 加载模型Model

    OpenGL 模型Model 模型Model简介 导入3D模型到OpenGL 从Assimp到网格 索引 材质 重大优化 和箱子模型告别 模型Model简介 现在是时候接触Assimp并创建实际的加载 ...

  5. php.ini开启命名空间,Zend Framework教程之模型Model基本规则和使用方法

    本文实例讲述了Zend Framework教程之模型Model基本规则和使用方法.分享给大家供大家参考,具体如下: 这里讲讲Zend中的model.其实Zend中的Model处理是相当简单的. 这主要 ...

  6. php 框架源码分析,Laravel框架源码解析之模型Model原理与用法解析

    本文实例讲述了Laravel框架源码解析之模型Model原理与用法.分享给大家供大家参考,具体如下: 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看着你们. 根据单一责任开发原则来讲, ...

  7. Django 模型Model层2

    多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对 ...

  8. Qt模型model、视图view、代理

    例子为qt5应用及实例第8章 MVC是一种与用户界面相关的设计模式.通过使用此模型,可以有效地分离数据和用户界面.MVC设计模式包含三要素:表示数据的模型(Model).表示用户界面的视图(View) ...

  9. 梅科尔工作室-Django保姆级教程-2-ORM介绍与Model设计

    django开发-ORM介绍与Model设计_哔哩哔哩_bilibili 笔记链接如上 首先,了解这个 cursor  拿数据  返回数据 如果每次为了获得一个语句就要写这么多步骤  就很麻烦 所以使 ...

最新文章

  1. python3.5.0下载-python核心编程最新版下载
  2. python元组的方法_Python元组及其方法
  3. delphi TStrings的一些用法
  4. 《自卑与超越》读书笔记(part3)--做梦就是在保护我们的生活模式不被现实和常识所威胁
  5. 红帽Openshift:入门–云中的Java EE6
  6. 为什么要在JavaScript中使用静态类型? 我们是否应该使用它们?
  7. myeclipse下Tomcat java.lang.OutOfMemory Error: Java heap space
  8. 快速配置vs2012+opencv
  9. 使用ASP.NET Membership
  10. 使用微PE工具箱安装Win7
  11. SQL必知必会【极客时间笔记】
  12. 吞食天地2完全版乱码怎么解决_PDF转Word如何转换?PDF转Word乱码怎么解决?
  13. SPSS数据分析流程
  14. python for spss statistics_IBM SPSS Statistics 与用户自定义 Python 模块的集成及分析
  15. VS插件AnkhSVN的安装,设置和使用
  16. html3d转换浏览器设定,R:使用rgl生成可以在Web浏览器中查看的3d可旋转图形?
  17. 百度磁盘搜索和git、ssh的试用
  18. C语言初学者如何制作一个完整的C语言程序——歌曲排行榜
  19. SCZ的3篇有关sam的文章
  20. 三星手机动态修改分辨率信息

热门文章

  1. 侣信即时通讯系统全新发布
  2. wing ide 3.x 中文设置
  3. 聊聊Elasticsearch RestClient的RequestLogger
  4. android adb shell 常用命令
  5. POJ 2195 Going Home(最小费用最大流)题解
  6. 学习笔记之ulimit
  7. 数据结构-队列,优先队列
  8. 类似华容道一类搜索中,状态的Hash方法(转)
  9. HttpHandler解析并展示PDF文档内容
  10. cad命令栏还原默认_CAD十五个必学的命令 掌握后能走天下了