最簡單的Web組件和最複雜的線上電子商務Web網站具有一個共同點:它們都要處理資料。大量的編程都設計資料的訪問和操作。隨著Internet的發展、臉頰存放裝置應用資料的大量增長、對分析論的更深入理解以及對資料訪問的更大期待,資料以更加有趣和獨特的方式受到影響。資料訪問設計模式的目的是協助構造出能夠容易地處理素有這些資料的對象。
Data Access Objects設計模式描述了如何建立提供透明訪問任何對象源的對象。
Data Access Objects設計模式的目的是結局一下兩種特定的問題:重複與資料來源抽象化。
我們應當建立一個Data Access Objects設計模式的對象。這個Data Access Objects封裝了建立sQL調用、減少執行個體建立的複雜性和重複以及更新進程的智能方式,其編寫方式應當是:該對象的使用者不會知道實際使用的表結構和資料庫引擎。此外,這個對象應用的方法應當使用邏輯參數,並且應處理SQL語句的建立工作。
Data Access Objects模式的額外優點是提供資料庫抽象層。現在,應用程式的主要處理代碼不再需要考慮資料庫引擎或表關係。調用這種對象的公用方法會返回任何資料類型,並且不用考慮內在SQL需要的類型。
使用將非規格化表與另一個表相串連以提供特定結果集的關聯式資料庫結構能夠很好地說明這個問題。如果資料庫管理員將非規格化表結構修改為完全規格化的,那麼遍布應用程式中所有模組的每條SQL語句都需要被修改為添加額外的串連表。如果使用Data Access Objects,那麼就只需要編輯提供該資訊的方法。再來看一下實績表結構發生變化的情況:對一個列的命名可能發生變化,或者可能添加額外的列。同樣地,需要編輯代碼的仍然是Data Access Objects。SQL純粹主義者會堅決主張添加的表列應當完全不影響查詢,他們認為應當使用SQL語句中指定列。
如果編程人員沒有採用Data Access Objects設計模式,那麼總是會出現問題。將這些物件類型的全部與便於使用相對比,無疑添加更多功能的誘惑佔了統治地位。
管理Data Access Objects類中簡單性的一個好辦法是建立父-子關係。首先,建立一個基本的父物件。這個對象應當負責資料庫連接、抽象地執行查詢以及與子物件通訊。使用Data Access Objects設計模式時,最好開始就將一對一關聯性的子類與資料庫中的表相關聯。這些子類具有必不可少的資訊,如表名和主鍵。此外,子類可能包含一些特定的公用方法,這些方法通過只對子類有意義的方式執行父類的查詢。例如,名為userAddress的子類可能包含一個getAddreddesByZip()方法。將該方法放入父DAO類是毫無邏輯意義的,並且會破壞這個父類希望實現的抽象性。
處理引用特定資料庫資訊的實體時,最好的做法是建立一個Data Access Objects。
1 /* 2 *MySQL資料庫擁有一條記錄,該記錄包含對每個使用者來說都是具體和特有的資訊。這種功能性必須允許我們通過使用者的主鍵或對使用者名稱稱的尋找返回一個使用者。此外,我們必須能夠對使用者實體記錄的任意欄位執行更新操作。 3 針對此需求,需要使用兩個類:第一個類應當是基本Data Access Objects類,它具有擷取和更新資料方法: 4 * */ 5 6 abstract class baseDAO{ 7 private $__connection; 8 9 public function __construct(){10 $this->__connectionToDB(DB_USER,DB_PASS,DB_HOST,DB_DATABASE);11 }12 13 private function __connectToDB($user,$pass,$host,$database){14 $this->__connection = mysql_connection($host,$user,$pass);15 mysql_select_db($database,$this->__connection);16 }17 18 public function fetch($vale,$key = NULL){19 if(is_null($key)){20 $key = $this->_primaryKey;21 }22 23 $sql = "select * from {$this->_tablename} where {$key} = '{$value}'";24 25 $results = mysql_query($sql,$this->__connection);26 27 $rows = array();28 29 while($result = mysql_fetch_array($results)){30 $rows[] = $result;31 }32 33 return $rows;34 }35 36 37 public function update($keyedArray){38 $sql = "update {$this->_tableName} set ";39 40 $updates = array();41 42 foreach($keyedArray as $column =>$value){43 $updates[] = "{$column} = '{$value}'";44 }45 46 $sql .= implode(',',$updates);47 48 $sql = " where {$this->_primaryKey} = '{$keyedArray[$this->_primaryKey]}'";49 50 mysql_query($sql,$this->__connection);51 }52 }53 54 /*55 這是一個抽象類別,為了能夠使用該類必須擴充該類。56 因為很可能會同時開啟多個資料庫連接,所以在Data Access Objects類中儲存內部的資料庫連接並且每個查詢都進行引用是十分重要的。這個Data Access Objects類應當唯一地引用自其自己的串連。通常,在更多可拓展的模型中,介面被建立用於共用串連。57 58 */59 60 /*61 任何子類都可以任意擴充這個抽象類別:62 */63 64 class UserDAO extends baseDAO{65 protected $_tableName = "userTable";66 67 protected $_primaryKey = 'id';68 69 public function getUserByFirstName($name){70 $result = $this->fetch($name,'firstName');71 72 return $result;73 }74 }75 76 /*77 為了獲得一個起作用的Data Access Objects子實體,至少需要定義兩個受保護變數。78 79 要使用的Data Access Objects的樣本:80 */81 82 define('DB_USER','user');83 84 define('DB_PASS','pass');85 86 define('DB_HOST','localhost');87 88 define('DB_DATABASE','test');89 90 $user = new userDAO();91 92 $userDetailsArray = $user->fetch(1);93 94 $updates = array('id'=>1,'firstName'=>'aaron');95 96 $user->update($updates);97 98 99 $allAarons = $user->getUserByFirstName('aaron');
發現,ThinkPHP資料庫操作底層,除了支援多種資料庫引擎外,其實原理也是採用這種Data Access Objects模式。