子表物件

天笑發表於2017-03-14

子表物件

前面提到過想在物件中返回子表時,可以使用壓縮成一個字串的子表欄位,一般適合資料比較簡單的場合。

另一種方式是用$subobj來定義子表物件。

例如在獲取訂單時,同時返回訂單日誌,設計介面如下:

Ordr.get() -> {id, ..., @orderLog?}

返回
orderLog: {id, tm, dscr, action} 訂單日誌子表。

示例

{id: 1, dscr: "換輪胎及洗車", ..., orderLog: [
    {id: 1, tm: "2016-1-1 10:10", action: "CR", dscr: "建立訂單"},
    {id: 2, tm: "2016-1-1 10:20", action: "PA", dscr: "付款"}
]}

上面介面原型描述中,欄位orderLog前面的"@"標記表示它是一個陣列,在返回值介紹中列出了它的資料結構。

實現:

class AC1_Ordr extends AccessControl
{
    protected $subobj = [
        "orderLog" => ["sql"=>"SELECT ol.* FROM OrderLog ol WHERE ol.orderId=%d"]
    ];
}

用選項"sql"定義子表的查詢語句,其中用"%d"來表示主表主鍵,這裡即Ordr.id欄位。

定義子表物件時,還可設定一些選項,比如上面設定等價於:

    "orderLog" => ["sql"=>..., "wantOne"=>false, "default"=>false]
  • 選項"wantOne"表示是否只返回一行。預設是返回一個物件陣列,如[{id, tm, ...}]。 如果選項"wantOne"為true,則結果以一個物件返回即 {id, tm, ...}, 適用於主表與子表一對一的情況。

  • 選項"default"與虛擬欄位(vcolDefs)上的"default"選項一樣,表示當get或query介面未指定"res"引數時,是否預設返回該欄位。 一般應使用預設值false,客戶端需要時應通過res引數指定,如 Ordr.query(res="*,orderLog").

注意:查詢子表作為子物件欄位是不支援分頁的。如果子表可能很大,不要設計使用子表欄位或列表欄位,而應直接用子表的query方法來取,如開放介面"OrderLog.query"。

相關文章