數(shù)據(jù)映射模式(Data Mapper Pattern ):描述如何創(chuàng)建提供透明訪問任何數(shù)據(jù)源的對象。數(shù)據(jù)映射模式,也叫數(shù)據(jù)訪問對象模式,或數(shù)據(jù)對象映射模式。
(一)為什么需要數(shù)據(jù)映射模式
數(shù)據(jù)映射模式的目的是讓持久化數(shù)據(jù)存儲層、駐于內(nèi)存的數(shù)據(jù)表現(xiàn)層、以及數(shù)據(jù)映射本身三者相互獨立、互不依賴。這個數(shù)據(jù)訪問層由一個或多個映射器(或者數(shù)據(jù)訪問對象)組成,用于實現(xiàn)數(shù)據(jù)傳輸。通用的數(shù)據(jù)訪問層可以處理不同的實體類型,而專用的則處理一個或幾個。
(二)數(shù)據(jù)映射模式UML圖

Data Mapper Pattern
(三)簡單實例
通過數(shù)據(jù)對象映射模式,我們可以實現(xiàn)一個對象對應一條數(shù)據(jù)庫記錄,對象的屬性對應記錄的字段。但對象的屬性改變時,自動更新數(shù)據(jù)庫記錄。
例如我們有一個用戶類與數(shù)據(jù)庫的用戶表對應
<?php
//數(shù)據(jù)模式映射類
class User
{
protected $id;
protected $data;
protected $db;
protected $change = false;
public function __construct($id)
{
$this->id = $id;
//實例化數(shù)據(jù)庫對象,這里使用了工廠方法
$this->db = Factory::getDatabase();
//從數(shù)據(jù)庫查詢數(shù)據(jù),存放到data屬性中
$this->data = $this->db->query("select * from user where id = $id limit 1");
}
public function __get($key)
{
if (isset($this->data[$key]))
{
return $this->data[$key];
}
}
public function __set($key, $value)
{
$this->data[$key] = $value;
$this->change = true;
}
//析構方法
public function __destruct()
{
//如果對象屬性改變過,則change屬性為true 則調(diào)更新方法更新數(shù)據(jù)庫
$this->change && $this->update();
}
//更新記錄方法
public function update(){
foreach ($this->data as $k => $v)
{
$fields[] = "$k = '{$v}'";
}
$this->db->query("update user set " . implode(', ', $fields) . "where
id = {$this->id} limit 1");
}
}
//實例化對象
$user = new User(1);
//改變名字
$user->name = 'admin';
如果我們要實現(xiàn)實時更新,也可以不要change屬性,直接在__set方法中調(diào)用update方法,不用等到對象銷毀前再統(tǒng)一更新。當然實時更新時更新方法可以精簡地不需要foreach,只寫更新一個字段指令就OK,但是這樣也帶來頻繁操作數(shù)據(jù)庫的問題。