博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Symfony2Book04:Doctrine01-介绍模型(Model)
阅读量:5743 次
发布时间:2019-06-18

本文共 3225 字,大约阅读时间需要 10 分钟。

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

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

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

到底什么是模型

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

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

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

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

就是这样,现在你知道在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.  
  3. $manager->persist($post); 
  4. $manager->flush(); 

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

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

结论

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

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

本文转自 firehare 51CTO博客,原文链接:http://blog.51cto.com/firehare/585426,如需转载请自行联系原作者

你可能感兴趣的文章
深入理解 Android 之 View 的绘制流程
查看>>
Run_Product Example Form - Oracle Forms 6i
查看>>
Reading Csv Files with Text_io in Oracle D2k Forms
查看>>
Spring事务管理只对出现运行期异常进行回滚
查看>>
【BJG吐槽汇】第一期 - 警惕亚马逊莫名自动扣款!千万不要进了它的坑!
查看>>
禁止html上拖动图片打开新标签页
查看>>
第一章 Slenium2-Java 自动化测试基础
查看>>
安装vim-indent-guides 插件
查看>>
[Vue] Update Attributes, Classes and Styles in Vue.js with v-bind
查看>>
搭建consul 集群
查看>>
RocketMQ与kafka对比(官方)
查看>>
算法笔记_033:十六进制转八进制(Java)
查看>>
检测http方法是否开启put方法
查看>>
iOS应用跳转到App Store评分
查看>>
图片Ping
查看>>
inode表元数据,存储在物理存储体上
查看>>
点赞效果
查看>>
idea 换主题
查看>>
TreeMap
查看>>
meta 标签的学习
查看>>