=简介=
DB_DataObject将数据表封装成对象,所有对数据库的操作转化为对象的操作。
使用DataObject,完全不用跟[[SQL]]打交道。特别在需要修改数据库结构的时候,例如增加或删除表和字段、改名、更改表间关系,在设计一个稍为复杂的系统时,这些情况都会经常出现。使用DataObject,只需修改很少的几个地方,不用去修改讨厌的SQL语句。再配合其它几个类,例如FormBuilder,DataGrid,就能够用很简单的几行代码实现数据输入和输出显示等复杂功能。
很多人使用DB类,因为DB类隐藏了不同数据库的差异。但是你还是要直接使用SQL语句。DataObject在DB的基础上进一步抽象,隐藏了数据库。
*依赖关系
需要DB类的支持;DataObject_formBuilder依赖本类。
*优点与缺点
面向对象操作数据库,提高开发效率,适应变化,适合于迭代式开发。
=快速开始=
注意:由于[[Zend]]存在的一个bug,如果使用Zend,必须将DataObject.php文件中第121行
:define('DB_DATAOBJECT_NO_OVERLOAD',true);
的注释符去掉;或在每个用到DataObject的文件的前面加上这句。原文还漏了“;”,记得加上。如果初次运行浏览器死锁或出现找不到页面,多半是这个问题。
==在mysql中建立数据库==
例如
CREATE TABLE IF NOT EXISTS `hr_employee` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL default '',
`section_id` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
) TYPE=MyISAM COMMENT='员工表';
CREATE TABLE IF NOT EXISTS `hr_section` (
`id` tinyint(3) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) TYPE=MyISAM COMMENT='部门表' ;
CREATE TABLE IF NOT EXISTS `hr_project` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`name` varchar(60) NOT NULL default '',
`date` date NOT NULL default '0000-00-00',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) TYPE=MyISAM COMMENT='项目表' ;
CREATE TABLE IF NOT EXISTS `hr_employee_project` (
`id` int(11) unsigned NOT NULL auto_increment,
`employee_id` smallint(5) unsigned NOT NULL default '0',
`project_id` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `employee_id` (`employee_id`,`project_id`)
) TYPE=MyISAM COMMENT='员工-项目表';
==创建DataObject.ini==
[DB_DataObject]
database = mysql://user:password@server/database
schema_location = /DataObjects
class_location = /DataObjects
require_prefix = /DataObjects/
==创建CreateDataObjectClasses.php==
//注意设置好你的pear包含路径
require_once 'd:/www/Pear/DB/DataObject/Generator.php';
$config = parse_ini_file("D:wwwhrDataObjectsDataObject.ini", true);
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$options = $config['DB_DataObject'];
if (!$options) {
PEAR::raiseError("错误:无法读取ini文件", null, PEAR_ERROR_DIE);
exit;
}
set_time_limit(0);
DB_DataObject::debugLevel(1);
$generator = new DB_DataObject_Generator;
$generator->start();
?>
==运行CreateDataObjectClasses.php==
*在DataObjects目录中自动为数据库中每个表生一个DataObject的子类,存为相应的php文件。
*自动生成一个db.ini配置文件,db是你的数据库的名字。这个文件保存了每个表中各字段类型信息,用数字表示,是自动生成的,请不要修改这个表。
==创建db.link.ini==
[hr_employee]
section_id = hr_section:id
[hr_employee_project]
employee_id = hr_employee:id
project_id = hr_training_project:id
[hr_project]
id = hr_employee:id
上述步骤看起来复杂,做好了一切就简单了。这可以我摸索了近半个月才搞清楚的。
==现在可以开始了。==
//取单个表的数据
$employee = new Hr_employee;
$employee->name = '张三';
$employee->find(ture);
echo '员工'.$employee->name.'的职务是'.$employee->position.',';
//取多对一关系的数据
$employee->getLinks();
echo '工作部门是'.$employee->_section_id->name.',';
//取多对多关系的数据
echo '参加的项目包括';
$e_p = new Hr_employee_project;
$e_p->employee_id = $employee->id;
$e_p->find();
while ($e_p->fetch()) {
$project = $e_p->getLink('project_id');
echo $project->name.'、';
}
echo '。';
?>
=进阶=
==配置选项==
共有三个ini文件存放各种信息,
*DataObject.ini (或config.ini)名字由用户自己定义。设置数据库、路径等信息
*db.ini 执行CreateDataObjectClasses.php自动创建,保存数据库各字段的类型
*db.links.ini 保存表间关系,不同表通过什么字段来联系。
其中db用你的数据库名称替换。
===DataObject.ini===
信息放在[DB_DataObject]段内
[DB_DataObject]
database = mysql://user:password@server/database
schema_location = /DataObjects
class_location = /DataObjects
require_prefix = /DataObjects/
database:数据库访问信息,与DB的格式一样
schema_location:存放表间关系的ini文件
class_location:自动生成的DataObject类放置的路径
require_prefix:派生类放置的路径,最后为“/”。与include路径的相对路径。
staticGet()和getLinks()方法自动载入类时要搜索到相应的类。
一个linux下的例子:
[DB_DataObject]
database = mysql://user:password@localhost/vending
schema_location = /home/me/Projects/myapplication/DataObjects
class_location = /home/me/Projects/myapplication/DataObjects
require_prefix = DataObjects/
class_prefix = DataObjects_
也可以不使用ini文件的方式,而使用$options组件:
$config = parse_ini_file('example.ini',TRUE);
foreach($config as $class=>$values) {
$options = &PEAR::getStaticProperty($class,'options');
$options = $values;
}
// or you can do without an ini file, and configure it in PHP..
$options = &PEAR::getStaticProperty('DB_DataObject','options');
$options = array(
'database' => 'mysql://user:password@localhost/vending',
'schema_location' => '/home/me/Projects/myapplication/DataObjects',
'class_location' => '/home/me/Projects/myapplication/DataObjects',
'require_prefix' => 'DataObjects/',
'class_prefix' => 'DataObjects_',
);
上述四个是必先项,以下为可选项:
sequence_{table} string:强行设置次序键(autoincrement/nextval类型)。当主键不能被正确识别而运行不正确,
可以强行设置次序键
例如:sequence_person = login 将person表的次序键设为login字段。
ignore_sequence_keys string 忽略顺序键
If you do not want to use pear's nextval(), for automatically filling in sequences, this can disable it for "ALL", or a list of tables "person,cart,group"
debug integer 调试级别。这个选项非常有用,调试时可以看到运行的情况。
不过我一般会用->debug() 方法在一个公共文件中设置。默认为关闭 (default 0=off), 1= basic sql logging,2=result logging, 3=everything
debug_ignore_updates boolean
default FALSE, if set, then updates on the database are disabled.
dont_die boolean
default FALSE, The standard behaviour of dataobjects is to issue a PEAR_ERROR_DIE (eg. exiting PHP), when a fatal error occurs, like database connection failure or sending an invalid object type to a method. However if you need to run it on a live server you will probably want to set this to TRUE and define a PEAR error handler to catch these errors and show a nice friendly 'sorry we are down for maintenence' message page.
Configuration Options - Multiple Databases (optional)
database_* string
When you have multiple databases you can use the database_* to specify the DSN for each database
Example 20-4. using multiple databases - database passwords
database_authentication = mysql://user:password@localhost/authentication
database_sales = mysql://user:password@localhost/sales
table_* string
When you have multiple databases you can use the table_* configuration variables to map individual tables to different databases, for example
Example 20-5. using multiple databases - table settings
table_users = authentication
table_saleslog = sales
table_stock = sales
Configuration Options - Builder
class_location directory
The Directory where your DataObject extended Classes are.
Used by the Class Auto Builder when updating/writing to your class definitions.
extends string
The Name of your Base Class (usually DB_DataObject) is located.
If you wish to add a common layer of useful methods for all classes, you can set the extends_location and extends settings to a different class. the default is 'DB_DataObject'
extends_location directory
The Directory where your Base Class (usually DB_DataObject) is located.
If you wish to add a common layer of useful methods for all classes, you can set the extends_location and extends settings to a different class. the default is 'DB/DataObject.php'
generator_class_rewrite directory
===定义表间关系 db.links.ini===
==结构==
==表间关系==
1:1(一对一关系)
n:1(一对多关系,或者是多对一关系)
通常表示一个对象的属性也是一个对象。
n:m(多对多关系)
使用一个十字链表(crossLink table)表示它们之间的关系。
==对数据表的要求==
每个表的主键(primaryKey)必须是一个以唯一数字标识的字段(sequenceKey),在mysql中就是auto_increment的字段。不可以使用非整型的字段作为主键,即使是设为unique;也不可以用多字段做主键。这与数据库设计的理论有些不同。例如以username作为主键,会出现找不到键的错误。虽然可以用keys()方法强行设置主键,但我建议不要这样做。