使用实体

实体简单的讲就是你的应用程序中主要概念的代码代表,也是你将要使用的数据结构。你如果你已经了解实体,请直接跳到DB_DataObjects部分。

什么是实体?

如果你正在创建一个web应用程序,比如说blog,你会用到下列这些实体:

  • 文章
  • 用户
  • 评论

文章日期,用户名称不是实体吗?它们是‘属性’。注意实体必须是唯一的。更多关于实体和属性之间的区别在这篇文章里。另一个和实体紧密联系的概念是collections。collections是实体的列表和集合。collections实例:你的主页上的所有文章和相关的评论,某次查询的全部返回值。

在设计应用程序时,你可能有许多方法,你偶尔可能会遇到:

  • 决定你要处理哪些实体
  • 确保属性和实体正确区分了
  • 在数据库创建表
  • 建立处理数据的商务逻辑

面向对象通过下列概念使应用程序设计变得易于处理:

  • '数据封装' - 任何对象‘存储’了实体的所有属性;如果你的对象是复杂的,比如说Car对象,只要你正确定义了属性那么数据会变得容易管理起来。Car对象的所有动作会成为类Car的方法。
  • '数据连续性' - 如果你不能保存对象状态,那么你的应用程序将是毫无作用的。如果你想在页面间使用同一个对象,比如说User对象,你可以使用session。在不同的应用程序语言之间共用一个对象 ,如用户账户信息,你只需将它保存永久存储器中:如数据库中的一条记录,磁盘上的一个文件,LDAP目录下的一个实体等等。
  • '对象状态' - 无论什么时候你调用对象的方法来修改它的属性,你就修改了它的状态。按面向对象的规则,对象的所有私有属性都不能被其它对象直接访问,而只能通过getter/setter方法访问。然而在PHP4.x版本中,并不是强迫要这样而且直接修改属性通常是更方便的。

DB_DataObject

DB_DataObject是PEAR包关于实体管理的一个包。用作者Alan Knowles的话说:

DataObject 做了两件事情:

 1. 基于对象变量创建SQL语句和构造方法
 2. 作为表中一行的数据仓储。

内核类被设计成继承你的所有数据表,这样你就可以把数据逻辑放在数据类里。包含了一个创建配置文件和基类的生成器。

总有那么一个时候你的web要求你用某种特定方式管理实体,通学是执行通过下列的基本操作来修改对象的状态:

  • add (INSERT)
  • modify (UPDATE)
  • remove (DELETE)

括号内的词语是SQL语句中相似的单词。DataObjects所做的是封装你和数据的交互,使得更易于管理对象状态。这个包按照下列工作流程工作:

  • 在开始之前先安装PEAR库的包(Seagull默认包含)
  • 要使用在你的项目设计阶段你决定的实体,先在数据库中创建适当的数据表。
  • 执行createTables.php脚本来创建实体类。这些实体类和你的数据库中的表的名称相似(在Seagull中可以通过web界面的Maintenance部分实现)。
  • 使用DO API用统一的方式来管理所有的对象,而无须注意你add/modify/delete了多少属性。
$myObj = new DataObjects_User();  //  instantiate a User object 
$myObj->get(12);  //  get a specific User object (row in the db) 
$myObj->username = 'your username here';  //  getting/setting an attribute 
$myObj->update();  //  updating the object state in the DB
$myObj->insert();  //  insert if it's a new object 
$myObj->delete();  //  delete the object

优点

确实DO做了很多工作,但是你已经理解了基本概念。更多资料在DO文档。为了说明这种工作方式的好处,让我们比较一下没有使用DataObject和使用区别:

使用DO之前:

  • 我的应用程序有5个主要对象,每个对象有10个左右的属性。
  • 创建实体类,定义类变量和add/mod/delete方法。
  • 某一天客户让我修改他之前告诉我定义的10个属性中的9个,并另外添加了5个;这意味我将不得不:
    • modify the table in the DB;修改数据库中的表
    • modify the class vars for the object;修改类变量
    • 为每个属性修改get/set方法
    • 对所有的add/mod/delete做相应的修改

使用DO之后:

  • 也是某一天客户要抽血,他要求改变最近两个实体的所有属性,另外再加两个实体,每一个有50个左右的属性。
  • 你告诉他,‘没问题’,因为你用了DataObject,所以你通过phpMyAdmin很快的修改了数据库中的表,并使用DO脚本重新生成你的实体类。
  • 所用的全部时间: 如果没用DataObject将会占用10%的时间

总结

DB_Dataobject允许你通过封装对象数据更容易地管理和修改你的WEB应用程序中的复杂对象。

Linking and Joining 数据实体

DB_Dataobject0.3版本引入了创建link ini文件的功能。所以你可以使用它将行映射到其它数据库的列。这个ini文件名应试是'(数据库名).links.ini',并放在(Seagull)/var/cache/entities/目录中。

'(数据库名).links.ini'文件对每一个表准备了section,这样主键和外键彼此映射。

如果你的key(从column链接来的)使用了'full stop',getLinks()会在表格字段名称中从左到右匹配字符串'full stop',将'full stop‘替换成下划线,并将这个名称赋给对象变量。或者在使用joinAdd()方法时你可能想使用selectAs()方法决定来自不同对象的列以何种方式返回。

Example (databasename).links.ini File

;                       for table person
[person]
;                       link value of eyecolor to table colors, match name column
eyecolor = colors:name
;                       link value of owner to table grp, match id column
owner = grp:id
;                       link value of picture to table attachments, match id column
picture = attachments:id
 
;                       for a sales example with multiple links of a single column
[sales]
;                       for autoloading the car object into $sales->_car_id
car_id = car:id
;                       for autoloading the part number object into $sales->_car_id_partnum
car_id.partnum = part_numbers:car_id

Fetching Linked Entities

$person = new DataObjects_Person();
$person->eyeColour = 'red';
$person->find();
while ($person->fetch()) {
 
    // use the links.ini file to automatically load
    // the car object into $person->_car
    $person->getLinks();
 
    echo "{$person->name} has red eyes and owns a {$person->_car->type}\n";
}

Joining Entities for a SELECT

// and finally the most complex, using SQL joins and select as.
// the example would look like this.
 
$person = new DataObjects_Person();
$person->eyeColour = 'red';
 
// first, use selectAs as to make the select clauses match the column names.
$person->selectAs();
 
// now lets create the related element
$car = new DataObjects_Car();
 
// and for fun.. lets look for red eys and red cars..
$car->colour = 'red';
 
// add them together.
$person->joinAdd($car);
 
// since both tables have the column id in them, we need to reformat the query so
// that the car columns have a different name.
$person->selectAs($car,'car_%s');
 
$person->find();
while ($person->fetch()) {
    echo "{$person->name} has red eyes and owns a {$person->car_type}\n";
}
 
howto/managingentitieswithdbdataobject.txt · 最后更改: 2009/02/23 15:17 由 鑫豪
 
Except where otherwise noted, content on this wiki is licensed under the following license:GNU Free Documentation License 1.2