Symfony2Book04:Doctrine01-介绍模型(Model)

简介:

如果你想学习模型和超级模型的最新技术,本章将无法对你有所帮助。但如果你仅仅只是想学习一个模型,你应用程序中元数据的层,那么请阅读本章内容。本章所描述的模型用于构建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,如需转载请自行联系原作者

相关文章
|
12天前
组件v-model
组件v-model
19 0
|
1月前
|
JSON 前端开发 开发者
sap.ui.model.Model.checkUpdate 方法介绍
sap.ui.model.Model.checkUpdate 方法介绍
11 0
|
1月前
|
存储 JSON 供应链
sap.ui.model.Model.refresh 方法介绍
sap.ui.model.Model.refresh 方法介绍
38 0
|
8天前
|
JavaScript 编译器
组件 v-model
组件 v-model
|
3月前
|
JavaScript
v-model和:model的区别
v-model和:model的区别
35 0
|
12月前
|
SQL 关系型数据库 MySQL
Django model 层之Making Query总结1
Django model 层之Making Query总结
52 0
|
12月前
|
SQL 存储 缓存
Django model 层之Making Query总结2
Django model 层之Making Query总结
81 0
|
前端开发 关系型数据库 MySQL
ChainDesk-Beego之ORM模型Model介绍
beego ORM 是一个强大的 Go 语言 ORM 框架,orm模块主要是处理MVC中的M(models)。她的灵感主要来自Django ORM 和 SQLAlchemy。 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。
3270 0
|
数据格式 Python
Django model update的各种用法介绍
Django开发过程中对表(model)的增删改查是最常用的功能之一,本文介绍笔者在使用model update过程中遇到的那些事 [ 运行环境:Django2.0 ] model update常规用法 假如我们的表结构是这样的 class User(models.
1489 0