=簡介=
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()方法強行設置主鍵,但我建議不要這樣做。