數據映射模式(Data Mapper Pattern ):描述如何創建提供透明訪問任何數據源的對象。數據映射模式,也叫數據訪問對象模式,或數據對象映射模式。
(一)為什么需要數據映射模式
數據映射模式的目的是讓持久化數據存儲層、駐于內存的數據表現層、以及數據映射本身三者相互獨立、互不依賴。這個數據訪問層由一個或多個映射器(或者數據訪問對象)組成,用于實現數據傳輸。通用的數據訪問層可以處理不同的實體類型,而專用的則處理一個或幾個。
(二)數據映射模式UML圖
Data Mapper Pattern
(三)簡單實例
通過數據對象映射模式,我們可以實現一個對象對應一條數據庫記錄,對象的屬性對應記錄的字段。但對象的屬性改變時,自動更新數據庫記錄。
例如我們有一個用戶類與數據庫的用戶表對應
<?php
//數據模式映射類
class User
{
protected $id;
protected $data;
protected $db;
protected $change = false;
public function __construct($id)
{
$this->id = $id;
//實例化數據庫對象,這里使用了工廠方法
$this->db = Factory::getDatabase();
//從數據庫查詢數據,存放到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 則調更新方法更新數據庫
$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';
如果我們要實現實時更新,也可以不要change屬性,直接在__set方法中調用update方法,不用等到對象銷毀前再統一更新。當然實時更新時更新方法可以精簡地不需要foreach,只寫更新一個字段指令就OK,但是這樣也帶來頻繁操作數據庫的問題。