引言
在數(shù)據(jù)庫(kù)表的設(shè)計(jì)時(shí),對(duì)不同的功能進(jìn)行切分,分割為不同的表進(jìn)行存儲(chǔ)。在業(yè)務(wù)邏輯中,再將需要連接的數(shù)據(jù)進(jìn)行整合輸出。
今天我們說(shuō)一說(shuō),在Laravel中,如何關(guān)聯(lián)模型,以及制定返回列,以精簡(jiǎn)返回?cái)?shù)據(jù)。
學(xué)習(xí)時(shí)間假如有兩個(gè)模型 User 和 Post,一個(gè)用戶會(huì)發(fā)布多個(gè)post,也就是一對(duì)多的關(guān)聯(lián)關(guān)系。在User模型中,指定此關(guān)系:
public function post(){ return $this->hasmany('Post'); }
反過(guò)來(lái),在Post模型中,必然有一個(gè)發(fā)布者,是一對(duì)一的映射:
public function user(){ return $this->belongsTo('User'); }
現(xiàn)在假如有一個(gè)查詢,獲取所有的帖子,并返回發(fā)布者的信息。如下:
public function getAllPosts() { return Post::with('user')->get(); }
這樣在返回值中,就可以使用 $post->user 返回 User 模型,并訪問(wèn)其屬性和方法。經(jīng)過(guò)框架整合后的 SQL 語(yǔ)句大概是這樣的:
select * from `posts` select * from `users` where `users`.`id` in (<1>, <2>)
顯然,第二條SQL語(yǔ)句,返回了user表的所有列,數(shù)據(jù)量有可能很大。是否可以返回指定列呢?這樣可以精簡(jiǎn)輸出,減少M(fèi)ySQL的傳輸負(fù)荷。
with語(yǔ)句模型的with語(yǔ)句用于調(diào)用模型內(nèi)聲明的關(guān)聯(lián)關(guān)系,其實(shí)它接收一個(gè)數(shù)組,可以在查詢時(shí)關(guān)聯(lián)多張表,同時(shí)支持一個(gè)閉包,用于對(duì)關(guān)聯(lián)表的查詢語(yǔ)句進(jìn)行裁切。
如上一節(jié)要指定user表的列,可以這樣寫(xiě):
Post::with(array('user'=>function($query){ $query->select('id','username'); }))->get();
閉包內(nèi)$query拼接SQL語(yǔ)句,并指定 select 選取的列,那么框架生成的SQL語(yǔ)句,就只會(huì)返回 id,username 列。
關(guān)聯(lián)關(guān)系我們注意到,在關(guān)聯(lián)關(guān)系的聲明上,第一節(jié)僅使用了 belongTo,hasMany 這樣的屬性,其實(shí)還可以鏈?zhǔn)秸{(diào)用。這樣對(duì)于所有使用 with 語(yǔ)句關(guān)聯(lián)的模型查詢,都會(huì)生效。
沒(méi)錯(cuò)兒,接著關(guān)聯(lián)關(guān)系用下去。比如Post模型內(nèi):
public function user() { return $this->belongsTo('User')->select(array('id', 'username')); }
特殊性在Laravel5.5及以上的版本,支持在使用with語(yǔ)句的使用,按照格式書(shū)寫(xiě)返回指定列。
Post::with('user:id,username')->get();
低版本可就沒(méi)有那么好運(yùn)氣了!:-(
寫(xiě)在最后本文通過(guò)2種確切可用的方式,裁剪了關(guān)聯(lián)模型返回列的內(nèi)容。
在實(shí)際代碼中,第一種使用閉包修剪SQL語(yǔ)句,用途較為廣泛。
第二種方式影響全局,一般不推薦。
第三種則是第一種的變體,但是對(duì)版本有要求。
Happy coding :-)
我是 @程序員小助手 ,持續(xù)分享編程知識(shí),歡迎關(guān)注。