例項講解TP5中關聯模型
https://blog.csdn.net/github_37512301/article/details/75675054
一、關聯模型
在關係型資料庫中,表之間有一對一、一對多、多對多的關係。在 TP5 中,實現了ORM (Object Relational Mapping) 的思想,通過在模型中建立模型間的關聯,實現建立表與表之間的關聯。
二、文章中用到的表結構
所用的資料表和資料傳到了百度雲
連結:http://pan.baidu.com/s/1hrXwEJa 密碼:9r98
image 表,儲存圖片的位置資訊
banner 推薦位表,儲存推薦位的型別
banner_item 表,推薦位中的資訊條目,可以看到它擁有外來鍵 img_id
theme 表,商品活動主題,包含頭圖,主題圖
product 表,商品表
theme_product 表, theme 與 product 的中間表
可以建立以下的 E-R圖,一個 banner可以用有多個 banner_item,一個banner_iten 擁有一個 image;
theme 與 product 是多對多關係,
圖1 表之間關係
三、從問題出發講解關聯
(1)查詢 banner 幷包含其下的 banner_item
由圖1可知,我們要在 banner 與 banner_item 之間建立一對多的關聯關係
classBanner extends Model { public function items() { //建立一對多關聯 return $this->hasMany('BannerItem', 'banner_id', 'id'); //關聯的模型,外來鍵,當前模型的主鍵 } public static function getBannerByID($id) { $banner = self::with('items')->find($id); // 通過 with 使用關聯模型,引數為關聯關係的方法名 return$banner; } }
查詢資料可得以下結果
{ "id": 1, "name": "首頁置頂", "description": "首頁輪播圖", "items": [ { "id": 1, "img_id": 65, "key_word": "6", "type": 1, "banner_id": 1 }, { "id": 2, "img_id": 2, "key_word": "25", "type": 1, "banner_id": 1 }, { "id": 3, "img_id": 3, "key_word": "11", "type": 1, "banner_id": 1 }, { "id": 5, "img_id": 1, "key_word": "10", "type": 1, "banner_id": 1 } ] }
可以發現,在 items 下為一個數組,說明一個 banner 包含多個 banner_item ,有一個問題, items下面是 img_id,客戶端需要圖片路徑,不需要 img_id,所以我們還需要建立 BannerItem 與 Image 模型間的關係。這時,Banner 與 BannerItem有一對多關聯,BannerItem 與 Image 有一對一關聯,這種關聯在 TP5 中稱為巢狀關聯。繼續完善程式碼。
BannerItem.php
class BannerItem extends Model { protected $hidden = ['delete_time', 'update_time']; /** * 建立與 Image 表的關聯模型(一對一) * @return \think\model\relation\BelongsTo */ public function img() { return $this->belongsTo('Image', 'img_id', 'id'); //關聯模型名,外來鍵名,關聯模型的主鍵 } }
Banner.php
class Banner extends Model { public function items() { return $this->hasMany('BannerItem', 'banner_id', 'id'); } public static function getBannerByID($id) { $banner = self::with(['items', 'items.img'])->find($id); // with 接收一個數組 return $banner; } }
這裡 items.img 這種語法並不太好理解,我們可以根據語境解釋,在一個 Banner 下需要包含多個 BannerItem,而每個 BannerItem 下面又對應一個 Image。
查詢結果:
{ "id": 1, "name": "首頁置頂", "description": "首頁輪播圖", "items": [ { "id": 1, "img_id": 65, "key_word": "6", "type": 1, "banner_id": 1, "img": { "url": "http://z.cn/images/banner-4a.png" } }, { "id": 2, "img_id": 2, "key_word": "25", "type": 1, "banner_id": 1, "img": { "url": "http://z.cn/images/banner-2a.png" } }, { "id": 3, "img_id": 3, "key_word": "11", "type": 1, "banner_id": 1, "img": { "url": "http://z.cn/images/banner-3a.png" } }, { "id": 5, "img_id": 1, "key_word": "10", "type": 1, "banner_id": 1, "img": { "url": "http://z.cn/images/banner-1a.png" } } ] }
這樣的結果就可以被客戶端處理了。
(2)hasOne 與 belongsTo 的區別
一對一關係,存在主從關係(主表和從表 ),主表不包含外來鍵,從表包含外來鍵。
hasOne 和 belongsTo 都是一對一關係,區別:
在主表的模型中建立關聯關係,用 hasOne
在從表模型中建立關聯關係,用 belongsTo
所以,我們在 BannerItem 中建立與 Image 的關係,用的是 belongsTo ,而不是 hasOne。相反,如果想在 Image 中查詢到 BannerItem 的內容,需要用 hasOne 。
(3)查詢 theme 幷包含其下的 product
為了讓查詢的主題包含圖片,所以我們要建立 theme 與 product 和 image 的關聯關係,theme 中 topic_img_id 和 head_img_id 與 image 的 id 都是一對一的關係,theme 與 product 是多對多關聯。
class Theme extends Model { /** * 建立 theme 表中 topic_img_id 與 image 表 id 的一對一關係 * @return \think\model\relation\BelongsTo */ public function topicImg() { return $this->belongsTo('Image', 'topic_img_id', 'id'); } public function headImg() { return $this->belongsTo('Image', 'head_img_id', 'id'); } /** * 建立多對多關聯模型 * @return \think\model\relation\BelongsToMany */ public function products() { //關聯模型名,中間表名,外來鍵名,當前模型外來鍵名 return $this->belongsToMany('Product', 'theme_product', 'product_id', 'theme_id'); } /** * 返回 theme和poducts * @id theme id * @return theme資料模型 */ public static function getThemeWithProducts($id) { $theme = self::with('products,topicImg,headImg') ->find($id); return $theme; } }
查詢結果為
[ { "id": 1, "name": "專題欄位一", "description": "美味水果世界", "topic_img_id": 16, "delete_time": null, "head_img_id": 49, "update_time": "1970-01-01 08:00:00", "topic_img": { "url": "http://z.cn/images/[email protected]" }, "head_img": { "url": "http://z.cn/images/[email protected]" } }, { "id": 2, "name": "專題欄位二", "description": "新品推薦", "topic_img_id": 17, "delete_time": null, "head_img_id": 50, "update_time": "1970-01-01 08:00:00", "topic_img": { "url": "http://z.cn/images/[email protected]" }, "head_img": { "url": "http://z.cn/images/[email protected]" } }, { "id": 3, "name": "專題欄位三", "description": "做個幹物女", "topic_img_id": 18, "delete_time": null, "head_img_id": 18, "update_time": "1970-01-01 08:00:00", "topic_img": { "url": "http://z.cn/images/[email protected]" }, "head_img": { "url": "http://z.cn/images/[email protected]" } } ]
可以看到,有的屬性前端並不需要使用,比如 topic_img_id,delete_time等,所以還需要隱藏欄位
在 Theme.php 中加入
protected $hidden = ['topic_img_id', 'head_img_id', 'delete_time', 'update_time'];
這裡只是結合例子,講了關聯模型的簡單使用。祝大家學習愉快。