<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 關聯模型 [上一頁](77.html "上一頁")[下一頁](79.html "下一頁") ### 關聯關系 通常我們所說的關聯關系包括下面三種: 一對一關聯 :ONE_TO_ONE,包括HAS_ONE和BELONGS_TO 一對多關聯 :ONE_TO_MANY,包括HAS_MANY和BELONGS_TO 多對多關聯 :MANY_TO_MANY 關聯關系必然有一個參照表,例如: 有一個員工檔案管理系統項目,這個項目要包括下面的一些數據表:基本信息表、員工檔案表、部門表、項目組表、銀行卡表(用來記錄員工的銀行卡資料)。 這些數據表之間存在一定的關聯關系,我們以員工基本信息表為參照來分析和其他表之間的關聯: 每個員工必然有對應的員工檔案資料,所以屬于HAS_ONE關聯; 每個員工必須屬于某個部門,所以屬于BELONGS_TO關聯; 每個員工可以有多個銀行卡,但是每張銀行卡只可能屬于一個員工,因此屬于HAS_MANY關聯; 每個員工可以同時在多個項目組,每個項目組同時有多個員工,因此屬于MANY_TO_MANY關聯; 分析清楚數據表之前的關聯關系后,我們才可以進行關聯定義和關聯操作。### 關聯定義 ThinkPHP可以很輕松的完成數據表的關聯CURD操作,目前支持的關聯關系包括下面四種:**HAS\_ONE、BELONGS\_TO、HAS\_MANY和MANY\_TO\_MANY**。 一個模型根據業務模型的復雜程度可以同時定義多個關聯,不受限制,所有的關聯定義都統一在模型類的 $_link 成員變量里面定義,并且可以支持動態定義。要支持關聯操作,模型類必須繼承RelationModel類,關聯定義的格式是:`protected?$_link?=?array(<br class="calibre5"></br>????'關聯1'??=>??array(<br class="calibre5"></br>????????'關聯屬性1'?=>?'定義',<br class="calibre5"></br>????????'關聯屬性N'?=>?'定義',<br class="calibre5"></br>????),<br class="calibre5"></br>????'關聯2'??=>??array(<br class="calibre5"></br>????????'關聯屬性1'?=>?'定義',<br class="calibre5"></br>????????'關聯屬性N'?=>?'定義',<br class="calibre5"></br>????),<br class="calibre5"></br>????'關聯3'??=>??HAS_ONE,?//?快捷定義<br class="calibre5"></br>????...<br class="calibre5"></br>);`下面我們首先來分析下各個關聯方式的定義: **HAS\_ONE** HAS_ONE關聯表示當前模型擁有一個子對象,例如,每個員工都有一個人事檔案。我們可以建立一個用戶模型UserModel,并且添加如下關聯定義:`class?UserModel?extends?RelationModel{<br class="calibre5"></br>????protected?$_link?=?array(<br class="calibre5"></br>???????'Profile'=>?HAS_ONE,<br class="calibre5"></br>????);<br class="calibre5"></br>}`上面是最簡單的方式,表示其遵循了系統內置的數據庫規范,完整的定義方式是:`class?UserModel?extends?RelationModel{<br class="calibre5"></br>????protected?$_link?=?array(<br class="calibre5"></br>????????????'Profile'=>array(<br class="calibre5"></br>????????????'mapping_type'????=>HAS_ONE,<br class="calibre5"></br>?????????????????'class_name'????=>'Profile',<br class="calibre5"></br>?????????????????//?定義更多的關聯屬性<br class="calibre5"></br>??????????????……<br class="calibre5"></br>?????????????),<br class="calibre5"></br>?????????);<br class="calibre5"></br>}`關聯HAS_ONE支持的關聯屬性有:**mapping\_type** 關聯類型,這個在HAS\_ONE 關聯里面必須使用HAS\_ONE 常量定義。**class\_name** 要關聯的模型類名 例如,class\_name 定義為Profile的話則表示和另外的Profile模型類關聯,這個Profile模型類是無需定義的,系統會自動定位到相關的數據表進行關聯。**mapping\_name** 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。如果mapping\_name沒有定義的話,會取class\_name的定義作為mapping\_name。如果class\_name也沒有定義,則以數組的索引作為mapping\_name。**foreign\_key** 關聯的外鍵名稱 外鍵的默認規則是當前數據對象名稱\_id,例如: UserModel對應的可能是表think\_user (注意:think只是一個表前綴,可以隨意配置) 那么think\_user表的外鍵默認為 user\_id,如果不是,就必須在定義關聯的時候顯式定義 foreign\_key 。**condition** 關聯條件 關聯查詢的時候會自動帶上外鍵的值,如果有額外的查詢條件,可以通過定義關聯的condition屬性。**mapping\_fields** 關聯要查詢的字段 默認情況下,關聯查詢的關聯數據是關聯表的全部字段,如果只是需要查詢個別字段,可以定義關聯的mapping\_fields屬性。**as\_fields**直接把關聯的字段值映射成數據對象中的某個字段 這個特性是ONE\_TO\_ONE 關聯特有的,可以直接把關聯數據映射到數據對象中,而不是作為一個關聯數據。當關聯數據的字段名和當前數據對象的字段名稱有沖突時,還可以使用映射定義。**BELONGS\_TO** Belongs_to 關聯表示當前模型從屬于另外一個父對象,例如每個用戶都屬于一個部門。我們可以做如下關聯定義。`?'Dept'=>?BELONGS_TO`完整方式定義為: `'Dept'=>?array(??<br class="calibre5"></br>?????'mapping_type'=>BELONGS_TO,<br class="calibre5"></br>??????????'class_name'=>'Dept',<br class="calibre5"></br>??????????'foreign_key'=>'userId',<br class="calibre5"></br>??????????'mapping_name'=>'dept',<br class="calibre5"></br>???????????//?定義更多的關聯屬性<br class="calibre5"></br>????????……<br class="calibre5"></br>),`關聯BELONGS_TO定義支持的關聯屬性有:class\_name 要關聯的模型類名mapping\_name 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。foreign\_key 關聯的外鍵名稱mapping\_fields 關聯要查詢的字段condition 關聯條件parent\_key 自引用關聯的關聯字段 默認為parent\_id 自引用關聯是一種比較特殊的關聯,也就是關聯表就是當前表。as\_fields直接把關聯的字段值映射成數據對象中的某個字段**HAS\_MANY** HAS_MANY 關聯表示當前模型擁有多個子對象,例如每個用戶有多篇文章,我們可以這樣來定義:`'Article'=>?HAS_MANY`完整定義方式為: `'Article'=>?array(??<br class="calibre5"></br>????'mapping_type'=>HAS_MANY,<br class="calibre5"></br>????????????????????'class_name'=>'Article',<br class="calibre5"></br>????????????????????'foreign_key'=>'userId',<br class="calibre5"></br>????????????????????'mapping_name'=>'articles',<br class="calibre5"></br>????????????????????'mapping_order'=>'create_time?desc',<br class="calibre5"></br>?????????//?定義更多的關聯屬性<br class="calibre5"></br>????????……<br class="calibre5"></br>???????),`關聯HAS_MANY定義支持的關聯屬性有:class\_name要關聯的模型類名mapping\_name 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。foreign\_key 關聯的外鍵名稱 外鍵的默認規則是當前數據對象名稱\_id,例如: UserModel對應的可能是表think\_user (注意:think只是一個表前綴,可以隨意配置) 那么think\_user表的外鍵默認為 user\_id,如果不是,就必須在定義關聯的時候定義 foreign\_key 。parent\_key 自引用關聯的關聯字段 默認為parent\_id condition 關聯條件 關聯查詢的時候會自動帶上外鍵的值,如果有額外的查詢條件,可以通過定義關聯的condition屬性。mapping\_fields 關聯要查詢的字段 默認情況下,關聯查詢的關聯數據是關聯表的全部字段,如果只是需要查詢個別字段,可以定義關聯的mapping\_fields屬性。mapping\_limit 關聯要返回的記錄數目mapping\_order 關聯查詢的排序**MANY\_TO\_MANY** MANY_TO_MANY 關聯表示當前模型可以屬于多個對象,而父對象則可能包含有多個子對象,通常兩者之間需要一個中間表類約束和關聯。例如每個用戶可以屬于多個組,每個組可以有多個用戶: `'Group'=>MANY_TO_MANY`完整定義方式為: `array('mapping_type'=>MANY_TO_MANY,<br class="calibre5"></br>'class_name'=>'Group',<br class="calibre5"></br>'mapping_name'=>'groups',<br class="calibre5"></br>'foreign_key'=>'userId',<br class="calibre5"></br>'relation_foreign_key'=>'goupId',<br class="calibre5"></br>'relation_table'=>'think_gourpUser'<br class="calibre5"></br>)`MANY_TO_MANY支持的關聯屬性定義有:class\_name要關聯的模型類名mapping\_name 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。foreign\_key 關聯的外鍵名稱 外鍵的默認規則是當前數據對象名稱\_idrelation\_foreign\_key 關聯表的外鍵名稱 默認的關聯表的外鍵名稱是表名\_idmapping\_limit 關聯要返回的記錄數目mapping\_order 關聯查詢的排序relation\_table多對多的中間關聯表名稱多對多的中間表默認表規則是:數據表前綴_關聯操作的主表名_關聯表名 如果think_user 和 think_group 存在一個對應的中間表,默認的表名應該是 如果是由group來操作關聯表,中間表應該是 think_group_user,如果是從user表來操作,那么應該是think_user_group,也就是說,多對多關聯的設置,必須有一個Model類里面需要顯式定義中間表,否則雙向操作會出錯。 中間表無需另外的id主鍵(但是這并不影響中間表的操作),通常只是由 user_id 和 group_id 構成。 默認會通過當前模型的getRelationTableName方法來自動獲取,如果當前模型是User,關聯模型是Group,那么關聯表的名稱也就是使用 user_group這樣的格式,如果不是默認規則,需要指定relation_table屬性。### 關聯查詢 由于性能問題,新版取消了自動關聯查詢機制,而統一使用relation方法進行關聯操作,relation方法不但可以啟用關聯還可以控制局部關聯操作,實現了關聯操作一切盡在掌握之中。`$User?=?D("User");<br class="calibre5"></br>$user?=????$User->relation(true)->find(1);`輸出$user結果可能是類似于下面的數據:`array(<br class="calibre5"></br>'id'????????=>????1,<br class="calibre5"></br>'account'????=>????'ThinkPHP',<br class="calibre5"></br>'password'????=>????'123456',<br class="calibre5"></br>'Profile'????=>?array(<br class="calibre5"></br>'email'????????=>'liu21st@gmail.com',<br class="calibre5"></br>'nickname'????=>'流年',<br class="calibre5"></br>???),<br class="calibre5"></br>?)`我們可以看到,用戶的關聯數據已經被映射到數據對象的屬性里面了。其中Profile就是關聯定義的mapping_name屬性。 如果我們按照下面的方式定義了as_fields屬性的話,`????protected?$_link?=?array(<br class="calibre5"></br>????????'profile'=>array(<br class="calibre5"></br>????'mapping_type'????=>HAS_ONE,<br class="calibre5"></br>????????????????????'class_name'????=>'Profile',<br class="calibre5"></br>????'foreign_key'=>'userId',<br class="calibre5"></br>????'as_fields'=>'email,nickname',<br class="calibre5"></br>?????????),<br class="calibre5"></br>);`查詢的結果就變成了下面的結果`array(<br class="calibre5"></br>'id'????????=>????1,<br class="calibre5"></br>'account'????=>????'ThinkPHP',<br class="calibre5"></br>'password'????=>????'name',<br class="calibre5"></br>'email'????????=>'liu21st@gmail.com',<br class="calibre5"></br>'nickname'????=>'流年',<br class="calibre5"></br>?)`email和nickname兩個字段已經作為user數據對象的字段來顯示了。 如果關聯數據的字段名和當前數據對象的字段有沖突的話,怎么解決呢? 我們可以用下面的方式來變化下定義: 'as_fields'=>'email,nickname:username', 表示關聯表的nickname字段映射成當前數據對象的username字段。 默認會把所有定義的關聯數據都查詢出來,有時候我們并不希望這樣,就可以給relation方法傳入參數來控制要關聯查詢的。`$User?=?D("User");<br class="calibre5"></br>$user?=????$User->relation('Profile')->find(1);`關聯查詢一樣可以支持select方法,如果要查詢多個數據,并同時獲取相應的關聯數據,可以改成:`$User?=?D("User");<br class="calibre5"></br>$list?=????$User->relation(true)->Select();`如果希望在完成的查詢基礎之上 再進行關聯數據的查詢,可以使用`$User?=?D("User");<br class="calibre5"></br>$user?=?$User->find(1);<br class="calibre5"></br>//?表示對當前查詢的數據對象進行關聯數據獲取<br class="calibre5"></br>$profile?=?$User->relationGet("Profile");`事實上,除了當前的參考模型User外,其他的關聯模型是不需要創建的。### 關聯操作 除了關聯查詢外,系統也支持關聯數據的自動寫入、更新和刪除 **關聯寫入**`$User?=?D("User");<br class="calibre5"></br>$data?=?array();<br class="calibre5"></br>$data["account"]????=?"ThinkPHP";<br class="calibre5"></br>$data["password"]?=?"123456";<br class="calibre5"></br>$data["Profile"]????=?array(<br class="calibre5"></br>????'email'????=>'liu21st@gmail.com',<br class="calibre5"></br>????'nickname'????=>'流年',<br class="calibre5"></br>);<br class="calibre5"></br>$result?=$User->relation(true)->add($data);`這樣就會自動寫入關聯的Profile數據。 同樣,可以使用參數來控制要關聯寫入的數據:`$result?=?$User->relation("Profile")->add($data);`**關聯更新** 數據的關聯更新和關聯寫入類似`$User?=?D("User");<br class="calibre5"></br>$data["account"]????=?"ThinkPHP";<br class="calibre5"></br>$data["password"]?=?"123456";<br class="calibre5"></br>$data["Profile"]????=?array(<br class="calibre5"></br>????'email'????=>'liu21st@gmail.com',<br class="calibre5"></br>????'nickname'????=>'流年',<br class="calibre5"></br>);<br class="calibre5"></br>$result?=?$User->?relation(true)->where('id=3')->save($data);`Relation(true)會關聯保存User模型定義的所有關聯數據,如果只需要關聯保存部分數據,可以使用:`$result?=?$User->relation("Profile")->save($data);`這樣就只會同時更新關聯的Profile數據。 關聯保存的規則: HAS_ONE: 關聯數據的更新直接賦值 HAS_MANY: 的關聯數據如果傳入主鍵的值 則表示更新 否則就表示新增 MANY_TO_MANY: 的數據更新是刪除之前的數據后重新寫入**關聯刪除** 刪除用戶ID為3的記錄的同時刪除關聯數據`$result?=?$User->relation(true)->delete("3");`如果只需要關聯刪除部分數據,可以使用`$result?=?$User->relation("Profile")->delete("3");` [上一頁](77.html "上一頁")[下一頁](79.html "下一頁")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看