資料源架構模式之行資料入口

巴扎黑
發布: 2016-11-12 10:55:38
原創
1590 人瀏覽過

註:看不懂的請勿踩,此文章非針對java,java愛好者可直接略過。

一、概念

行資料入口(Row Data Gateway):充當資料來源中單一記錄入口的對象,每行一個實例。

二、簡單實作行資料入口

為了方便理解,還是先簡單實作:

<?php
/**
 * 行数据入口类
 */
class OrderGateway {
    /*定义元数据映射*/
    private $_name;
    private $_id;
 
    public function __construct($id, $name) {
        $this->setId($id);
        $this->setName($name);
    }
 
    public function getName() {
        return $this->_name;
    }
 
    public function setName($name) {
        $this->_name = $name;
    }
 
    public function getId() {
        return $this->_id;
    }
 
    public function setId($id) {
        $this->_id = $id;
    }
 
    /**
     * 入口类自身拥有更新操作
     */
    public function update() {
        $data = array(&#39;id&#39; => $this->_id, &#39;name&#39; => $this->_name);
 
        $sql = "UPDATE order SET ";
        foreach ($data as $field => $value) {
            $sql .= "`" . $field . "` = &#39;" . $value . "&#39;,";
        }
        $sql = substr($sql, 0, -1);
        $sql .= " WHERE id = " . $this->_id;
        return DB::query($sql);
    }
 
    /**
     * 入口类自身拥有插入操作
     */
    public function insert() {
        $data = array(&#39;name&#39; => $this->_name);
 
        $sql = "INSERT INTO order ";
        $sql .= "(`" . implode("`,`", array_keys($data)) . "`)";
        $sql .= " VALUES(&#39;" . implode("&#39;,&#39;", array_values($data)) . "&#39;)";
 
        return DB::query($sql);
    }
 
    public static function load($rs) {
        /* 此处可加上缓存 */
        return new OrderGateway($rs[&#39;id&#39;] ? $rs[&#39;id&#39;] : NULL, $rs[&#39;name&#39;]);
    }
 
}
 
/**
 * 为了从数据库中读取信息,设置独立的OrderFinder娄。
 */
class OrderFinder {
    public function find($id) {
        $sql = "SELECT * FROM order WHERE id = " . $id;
        $rs = DB::query($sql);
 
        return OrderGateway::load($rs);//这里返回的行对象
    }
 
    public function findAll() {
        $sql = "SELECT * FROM order";
        $rs = DB::query($sql);
 
        $result = array();
        if (is_array($rs)) {
            foreach ($rs as $row) {
                $result[] = OrderGateway::load($row);
            }
        }
 
        return $result;
    }
 
}
 
class DB {
 
    /**
     * 这只是一个执行SQL的演示方法
     * @param string $sql   需要执行的SQL
     */
    public static function query($sql) {
        echo "执行SQL: ", $sql, " <br />";
    }
}
 
/**
 * 客户端调用
 */
class Client {
    public static function main() {
        header("Content-type:text/html; charset=utf-8");
 
        /* 写入示例 */
        $data = array(&#39;name&#39; => &#39;start&#39;);
        $order = OrderGateway::load($data);
        $order->insert();
 
        /* 更新示例 */
        $data = array(&#39;id&#39; => 1, &#39;name&#39; => &#39;stop&#39;);
        $order = OrderGateway::load($data);
        $order->setName(&#39;xxxxxx&#39;);
        $order->update();
 
        /* 查询示例 */
        $finder = new OrderFinder();
        $order = $finder->find(1);
        echo $order->getName();
    }
}
 
Client::main();
?>
登入後複製

三、運作機制

●行資料入口是單筆記錄極為相似的對象,在該物件中資料庫中的每一列為一個域。

●行資料入口一般能實現從資料來源類型到記憶體中類型的任意轉換。

●行資料入口不存在任何領域邏輯,如果存在,則是活動記錄。

●在實例可看到,為了從資料庫中讀取訊息,設定獨立的OrderFinder類別。當然這裡也可以選擇不新建類,採用靜態查找方法,但是它不支援需要為不同資料來源提供不同查找方法的多態。因此這裡最好單獨設定查找方法的物件。

●行資料入口除了可以用於表格外還可以用於視圖。需要注意的是視圖的更新操作。

●在程式碼中可見“定義元資料映射”,這是一種很好的做法,這樣一來,所有的資料庫存取程式碼都可以在自動建立過程中自動產生。

四、使用場景

4.1 事務腳本

可以很好地分離資料庫存取程式碼,並且也很容易被不同的事務腳本重複使用。不過可能會發現業務邏輯在多個腳本中重複出現,這些邏輯可能在行資料入口中有用。不斷移動這些邏輯會使行資料入口演變為活動記錄,這減少了業務邏輯的重複。

4.2 領域模型

如果要改變資料庫的結構但不想改變領域邏輯,採用行資料入口是不錯的選擇。大多數情況,資料映射器更適合領域模型。

行資料入口能和資料映射器一起配合使用,儘管這樣看起來有點多此一舉,不過,當行資料入口從元資料自動生成,而資料映射器由手動實現時,這種方法會很有效。

4.3 表模組(不考慮)


來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!