筋斗雲接口編程 / 虛擬表和視圖

虛擬表和視圖

表ApiLog中有一個字段叫app,表示前端應用名:

@ApiLog: id, tm, addr, app, userId

- userId: 如果app=user,則關聯到User表;如果app=emp,則關聯到員工表Employee

@Employee: id, name, phone, ...
@User: id, ...

當app=”emp”時,就表示是員工端應用的操作日誌。
現在想對員工端操作日誌進行查詢,定義以下接口:

EmpLog.query() -> tbl(id, tm, userId, ac, ..., empName?, empPhone?)

返回
- empName/empPhone: 關聯字段,通過userId關聯到Employee表的name/phone字段。

應用邏輯
- 權限:AUTH_EMP

EmpLog是一個虛擬對象或虛擬表,實現時,一種辦法是可以在數據庫定義一個視圖,如:

CREATE VIEW EmpLog AS
SELECT t0.id, tm, userId, ac, e.name empName, e.phone empPhone
FROM ApiLog t0
LEFT JOIN Employee e ON e.id=t0.userId
WHERE t0.app='emp' AND t0.userId IS NOT NULL
ORDER BY t0.id DESC

然後可將該視圖當作表一樣查詢(但不可更新),如:

class AC2_EmpLog extends AccessControl 
{
    protected $allowedAc = ["query"];
}

這樣就可以實現上述接口了。

另一種辦法是直接使用AccessControl創建虛擬表,代碼如下:

class AC2_EmpLog extends AccessControl 
{
    protected $allowedAc = ["query"];
    protected $table = 'ApiLog';
    protected $defaultSort = "t0.id DESC";
    protected $defaultRes = "id, tm, userId, ac, req, res, reqsz, ressz, empName, empPhone";
    protected $vcolDefs = [
        [
            "res" => ["e.name AS empName", "e.phone AS empPhone"],
            "join" => "LEFT JOIN Employee e ON e.id=t0.userId"
        ]
    ];

    // get/query操作都會走這裏
    protected function onQuery() {
        $this->addCond("t0.app='emp' and t0.userId IS NOT NULL");
    }
}

與上例相比,它不僅無須在數據庫中創建視圖,還也可以進行更新。
其要點是:

  • 重寫$table屬性, 定義實際表
  • 用屬性$vcolDefs定義虛擬字段
  • 用addCond方法添加缺省查詢條件

屬性$defaultSort$defaultRes可用於定義缺省返回字段及排序方式。

在get/query接口中可以用”res”指定返回字段,如果未指定,則會返回除了$hiddenFields定義的字段之外,所有主表中的字段,還會包括設置了default=>true的虛擬字段。
通過$defaultRes可以指定缺省返回字段列表。

query接口中可以通過”orderby”來指定排序方式,如果未指定,默認是按id排序的,通過$defaultSort可以修改默認排序方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章