摘要:方法返回一個列表,方法永遠(yuǎn)只返回一個結(jié)果。如果有多個結(jié)果,則只返回第一個。表的字段可以用從關(guān)聯(lián)的那獲得,但那是對象里面的。
表結(jié)構(gòu)
article文章表:aritlceid,content,id(文章發(fā)表人的id)
comment評論表:commentid,content,id(評論人的id),articleid(外鍵)
reply回復(fù)表:replyid,content,id(回復(fù)人的id),commentid(外鍵)
user用戶表:id,name
關(guān)聯(lián)關(guān)系基于yii 1.16
article->comment->reply,從左到右,兩兩之間是一對多關(guān)系,當(dāng)然發(fā)過來,從右到左是多對一關(guān)系。
上面每個表與user之間的關(guān)系是多對一關(guān)系.
article.php
array(self::HAS_MANY, "comment", "articleid"), "user"=>array(self::BELONGS_TO, "user", "id") ); } }
comment.php
array(self::BELONGS_TO, "article", "articleid"), "replys"=>array(self::HAS_MANY, "reply", "commentid"), "user"=>array(self::BELONGS_TO, "user", "id") ); } }
reply.php
array(self::BELONGS_TO, "user", "id"), "comment"=>array(self::BELONGS_TO,"comment","commentid") ); } }
user.php
查詢 符合要求的article 所有字段選取articleid=1的文章
$article=Article::model()->find(array( "condition"=>"articleid=:articleid", "params"=>array(":articleid"=>1) )); foreach ($article as $key => $value) { var_dump($key); var_dump($value); echo "部分字段
"; }$article=Article::model()->find(array( "select"=>"content", "condition"=>"articleid=:articleid", "params"=>array(":articleid"=>1) ));選取article及其對應(yīng)的comment這里有一對多關(guān)聯(lián),就不用懶加載了.
$articles=Article::model()->with(array("comments"))->findAll();輸出
foreach ($articles as $article) { echo "
"; var_dump($article->articleid); var_dump($article->id); var_dump($article->content); echo "
"; foreach ($article->comments as $key => $value) { var_dump($value->commentid); var_dump($value->content); var_dump($value->id); echo "
"; } }
可以看到,active record確實(shí)選取了第一篇文章及其下面的5條評論,第二篇文章及其下面的2條評論,以及后面的三篇文章,它們下面沒有評論。findAll()方法返回一個列表,find()方法永遠(yuǎn)只返回一個結(jié)果。如果有多個結(jié)果,則只返回第一個。
with()方法一次性加載關(guān)聯(lián)
加載article關(guān)聯(lián)的user表$articles=Article::model()->with(array("user","comments"))->findAll();輸出
foreach ($articles as $article) { ... var_dump($article->user->name); echo "加載comment關(guān)聯(lián)的user表
"; }$articles=Article::model()->with(array("user","comments","comments.user"))->findAll();這時會出現(xiàn)Syntax error or access violation: 1066 Not unique table/alias: "user",因?yàn)楸緦艖校阉卸鄬σ魂P(guān)聯(lián)都設(shè)置成"user"=>array(self::BELONGS_TO, "user", "id").如果comment設(shè)置成"comment_user"=>array(self::BELONGS_TO, "user", "id"),查詢變成
$articles=Article::model()->with(array("user","comments","comments.comment_user"))->findAll();就不會報錯了.
那么如果不改關(guān)聯(lián)怎么辦?Article::model()->with(array( "user", "comments", "comments.user"=>array("alias"=>"comment_user"))) ->findAll();with()方法也可以像find()方法那樣,傳入關(guān)聯(lián)數(shù)組作為參數(shù)。這里為comments.user設(shè)置一個別名就行了。
array( "alias"=>"article", ... )選取comment部分字段前面選取article部分字段時,用的是findAll(array("select"=>"...")),這里不能
Article::model()->with(array( "user", "comments", "comments.user"=>array("alias"=>"comment_user"))) ->findAll(array( "select"=>array("comments.content") ));應(yīng)該像上面為關(guān)聯(lián)添加別名那樣
Article::model()->with( array("user", "comments"=>array("select"=>"content"), "comments.user"=>array("alias"=>"comment_user") ))->findAll();輸出
foreach ($articles as $article) { ... foreach ($article->comments as $key => $value) { ... var_dump($value->user->name); echo "
"; } }選取comment對應(yīng)的reply
可以看到,comment表的id字段沒有值,content有值。
comment表的id字段可以用$value->user->id從關(guān)聯(lián)的user那獲得,但那是user對象里面的。這下有兩個一對多關(guān)系了
$articles=Article::model()->with(array( "user", "comments"=>array("select"=>"content"), "comments.user"=>array("alias"=>"comment_user"), "comments.replys")) ->findAll();輸出
foreach ($articles as $article) { ... foreach ($article->comments as $key => $value) { ... foreach ($value->replys as $key => $value) { var_dump($value->replyid); var_dump($value->content); var_dump($value->id); echo "
"; } echo "
"; } }
可以看到,只有第1,2條評論有回復(fù)。
事實(shí)上,如果不選取comment部分字段的話,可以直接$articles=Article::model()->with(array( "user", "comments.user"=>array("alias"=>"comment_user"), "comments.replys")) ->findAll();加載reply關(guān)聯(lián)的user表和前面comment關(guān)聯(lián)user一樣
Article::model()->with(array( "user", "comments"=>array("select"=>"content"), "comments.user"=>array("alias"=>"comment_user"), "comments.replys", "comments.replys.user"=>array("alias"=>"reply_user"))) ->findAll();選取reply部分字段Article::model()->with(array( "user", "comments"=>array("select"=>"content"), "comments.user"=>array("alias"=>"comment_user"), "comments.replys"=>array("select"=>"content"), "comments.replys.user"=>array("alias"=>"reply_user"))) ->findAll();條件查詢選取articleid=1的文章以及其評論,還有對應(yīng)的回復(fù)
Article::model()->with(array( "user", "comments.user"=>array("alias"=>"comment_user"), "comments.replys", "comments.replys.user"=>array("alias"=>"reply_user"))) ->findAll(array( "condition"=>"articleid=:articleid", "params"=>array(":articleid"=>1), "alias"=>"article" ));這時會報錯: Integrity constraint violation: 1052 Column "articleid" in where clause is ambiguous.還是命名沖突.在findAll()方法的參數(shù)里設(shè)置article別名,條件列前加上設(shè)置好的別名就行了。
Article::model()->with(array( "user", "comments.user"=>array("alias"=>"comment_user"), "comments.replys", "comments.replys.user"=>array("alias"=>"reply_user"))) ->findAll(array( "condition"=>"article.articleid=:articleid", "params"=>array(":articleid"=>1), "alias"=>"article" ));選取articleid=1且commentid=1的文章以及其評論,還有對應(yīng)的回復(fù)
Article::model()->with(array( "user", "comments.user"=>array("alias"=>"comment_user"), "comments.replys", "comments.replys.user"=>array("alias"=>"reply_user"))) ->findAll(array( "condition"=>"article.articleid=:articleid and comments.commentid=:commentid", "params"=>array(":articleid"=>1,":commentid"=>1), "alias"=>"article" ));注意,條件是comments.commentid=:commentid
comment,reply分頁和mybatis一樣,只能通過復(fù)雜的自定義sql實(shí)現(xiàn),參見本屌的mybatis Result Maps對結(jié)果分組3--一對多使用limit.寫完那糾結(jié)的sql后,調(diào)用Article::model()->findBySql($sql,$params)。
至于最后結(jié)果能否映射到對象上,或者說映射到對象上對選取的列的字段名有什么要求,本屌沒試過,不知道。
以后如果有什么新的發(fā)現(xiàn),會不定期更新此文。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/21198.html
摘要:建立關(guān)聯(lián)關(guān)系后,通過可以獲取一個對象的數(shù)組,該數(shù)組代表當(dāng)前客戶對象的訂單集。定義關(guān)聯(lián)關(guān)系使用一個可以返回對象的方法,對象有關(guān)聯(lián)上下文的相關(guān)信息,因此可以只查詢關(guān)聯(lián)數(shù)據(jù)。基于表外鍵定義關(guān)聯(lián)關(guān)系是最佳方法。 簡介 Yii 在操作數(shù)據(jù)庫方面提供了一個十分強(qiáng)大的類庫來支撐整個框架業(yè)務(wù)的運(yùn)轉(zhuǎn),這就是 Active Record (活動記錄,以下簡稱AR)。 基本概念 AR類提供了一個面向?qū)ο蟮慕?..
摘要:今天把這個問題講明白了,看看是怎么個多表關(guān)聯(lián)以及如何去優(yōu)化這個關(guān)聯(lián)。現(xiàn)需要在列表展示表的來源渠道,且該渠道可搜索。關(guān)聯(lián)表字段增加查詢中的搜索模型也是通過實(shí)現(xiàn)的,該模型通過控制著哪個字段可搜索,哪個字段不可搜索。 作者:白狼 出處:http://www.manks.top/yii2_many_ar_relation_search.html 本文版權(quán)歸作者,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留...
摘要:第二個參數(shù)是一個數(shù)組,其中鍵為所關(guān)聯(lián)的模型中的屬性,值為當(dāng)前模型中的屬性。這里注意中的第二個是指關(guān)聯(lián)的中的,第一個是指中的。 首先先來說明一下表結(jié)構(gòu) 表結(jié)構(gòu) 現(xiàn)在有訂單表、用戶表、商品清單表、商品庫存表 showImg(https://segmentfault.com/img/bVRcME?w=833&h=244); showImg(https://segmentfault.com/i...
摘要:前言是特有的用于多表關(guān)聯(lián)查詢的函數(shù),平時在使用多表關(guān)聯(lián)查詢的時候建議使用它們。需求分析使用一條查詢語句就能把列表的數(shù)據(jù)全部展現(xiàn)出來,列表包含一對一,一對多,以及多對多的關(guān)系。不能破壞自有的表頭排序功能,以及中的存值。相關(guān)資料中多表關(guān)聯(lián)查詢 前言 hasOne、hasMany是Yii2特有的用于多表關(guān)聯(lián)查詢的函數(shù),平時在使用多表關(guān)聯(lián)查詢的時候建議使用它們。為什么?因?yàn)檫@種方式關(guān)聯(lián)查詢出來...
閱讀 2648·2021-11-24 09:39
閱讀 1648·2021-11-24 09:38
閱讀 629·2021-11-22 14:44
閱讀 1888·2021-11-18 10:02
閱讀 2573·2021-11-18 10:02
閱讀 1158·2021-10-14 09:43
閱讀 4246·2021-09-29 09:35
閱讀 524·2021-07-30 15:30