<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 關聯關系 通常我們所說的關聯關系包括下面三種: ~~~ 一對一關聯 :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 成員變量里面定義,并且可以支持動態定義。要支持關聯操作,模型類必須繼承`Think\Model\RelationModel`類,關聯定義的格式是: ~~~ namespace Home\Model; use Think\Model\RelationModel; class UserModel extends RelationModel{ protected $_link = array( '關聯1' => array( '關聯屬性1' => '定義', '關聯屬性N' => '定義', ), '關聯2' => array( '關聯屬性1' => '定義', '關聯屬性N' => '定義', ), '關聯3' => HAS_ONE, // 快捷定義 ... ); } ~~~ 下面我們首先來分析下各個關聯方式的定義: ### HAS_ONE HAS_ONE關聯表示當前模型擁有一個子對象,例如,每個員工都有一個人事檔案。我們可以建立一個用戶模型UserModel,并且添加如下關聯定義: ~~~ namespace Home\Model; use Think\Model\RelationModel; class UserModel extends RelationModel{ protected $_link = array( 'Profile'=> self::HAS_ONE, ); } ~~~ 上面是最簡單的方式,表示其遵循了系統內置的數據庫規范,完整的定義方式是: ~~~ namespace Home\Model; use Think\Model\RelationModel; class UserModel extends RelationModel{ protected $_link = array( 'Profile'=>array( 'mapping_type' => self::HAS_ONE, 'class_name' => 'Profile', // 定義更多的關聯屬性 …… ), ); } ~~~ 關聯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' => self::BELONGS_TO ~~~ 完整方式定義為: ~~~ 'Dept' => array( 'mapping_type' => self::BELONGS_TO, 'class_name' => 'Dept', 'foreign_key' => 'userId', 'mapping_name' => 'dept', // 定義更多的關聯屬性 …… ), ~~~ 關聯BELONGS_TO定義支持的關聯屬性有: | 屬性 | 描述 | |-----|-----| | class_name | 要關聯的模型類名 | | mapping_name | 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。 | | foreign_key | 關聯的外鍵名稱 | | mapping_fields | 關聯要查詢的字段 | | condition | 關聯條件 | | parent_key | 自引用關聯的關聯字段 默認為parent_id 自引用關聯是一種比較特殊的關聯,也就是關聯表就是當前表。 | | as_fields | 直接把關聯的字段值映射成數據對象中的某個字段 | ### HAS_MANY HAS_MANY 關聯表示當前模型擁有多個子對象,例如每個用戶有多篇文章,我們可以這樣來定義: ~~~ 'Article' => self::HAS_MANY ~~~ 完整定義方式為: ~~~ 'Article' => array( 'mapping_type' => self::HAS_MANY, 'class_name' => 'Article', 'foreign_key' => 'userId', 'mapping_name' => 'articles', 'mapping_order' => 'create_time desc', // 定義更多的關聯屬性 …… ), ~~~ 關聯HAS_MANY定義支持的關聯屬性有: | 屬性 | 描述 | |-----|-----| | class_name | 要關聯的模型類名 | | mapping_name | 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。 | | foreign_key | 關聯的外鍵名稱 | | parent_key | 自引用關聯的關聯字段 默認為parent_id | | condition | 關聯條件 關聯查詢的時候會自動帶上外鍵的值,如果有額外的查詢條件,可以通過定義關聯的condition屬性。 | | mapping_fields | 關聯要查詢的字段 默認情況下,關聯查詢的關聯數據是關聯表的全部字段,如果只是需要查詢個別字段,可以定義關聯的mapping_fields屬性。 | | mapping_limit | 關聯要返回的記錄數目 | | mapping_order | 關聯查詢的排序 | 外鍵的默認規則是當前數據對象名稱_id,例如:UserModel對應的可能是表think_user (注意:think只是一個表前綴,可以隨意配置) 那么think_user表的外鍵默認為 user_id,如果不是,就必須在定義關聯的時候定義 foreign_key 。 ### MANY_TO_MANY MANY_TO_MANY 關聯表示當前模型可以屬于多個對象,而父對象則可能包含有多個子對象,通常兩者之間需要一個中間表類約束和關聯。例如每個用戶可以屬于多個組,每個組可以有多個用戶: ~~~ 'Group' => self::MANY_TO_MANY ~~~ 完整定義方式為: ~~~ 'Group' => array( 'mapping_type' => self::MANY_TO_MANY, 'class_name' => 'Group', 'mapping_name' => 'groups', 'foreign_key' => 'userId', 'relation_foreign_key' => 'groupId', 'relation_table' => 'think_group_user' //此處應顯式定義中間表名稱,且不能使用C函數讀取表前綴 ) ~~~ MANY_TO_MANY支持的關聯屬性定義有: | 屬性 | 描述 | |-----|-----| | class_name | 要關聯的模型類名 | | mapping_name | 關聯的映射名稱,用于獲取數據用 該名稱不要和當前模型的字段有重復,否則會導致關聯數據獲取的沖突。 | | foreign_key | 關聯的外鍵名稱 外鍵的默認規則是當前數據對象名稱_id | | relation_foreign_key | 關聯表的外鍵名稱 默認的關聯表的外鍵名稱是表名_id | | mapping_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屬性。 **3.2.2版本**開始,relation_table定義支持簡化寫法,例如: ~~~ 'relation_table'=>'__USER_GROUP__' ~~~ ## 關聯查詢 由于性能問題,新版取消了自動關聯查詢機制,而統一使用relation方法進行關聯操作,relation方法不但可以啟用關聯還可以控制局部關聯操作,實現了關聯操作一切盡在掌握之中。 ~~~ $User = D("User"); $user = $User->relation(true)->find(1); ~~~ 輸出$user結果可能是類似于下面的數據: ~~~ array( 'id' => 1, 'account' => 'ThinkPHP', 'password' => '123456', 'Profile' => array( 'email' => 'liu21st@gmail.com', 'nickname' => '流年', ), ) ~~~ 我們可以看到,用戶的關聯數據已經被映射到數據對象的屬性里面了。其中Profile就是關聯定義的mapping_name屬性。 如果我們按照下面的方式定義了as_fields屬性的話, ~~~ protected $_link = array( 'Profile'=>array( 'mapping_type' => self::HAS_ONE, 'class_name' => 'Profile', 'foreign_key' => 'userId', 'as_fields' => 'email,nickname', ), ); ~~~ 查詢的結果就變成了下面的結果 ~~~ array( 'id' => 1, 'account' => 'ThinkPHP', 'password' => 'name', 'email' => 'liu21st@gmail.com', 'nickname' => '流年', ) ~~~ email和nickname兩個字段已經作為user數據對象的字段來顯示了。 如果關聯數據的字段名和當前數據對象的字段有沖突的話,怎么解決呢? 我們可以用下面的方式來變化下定義: ~~~ 'as_fields' => 'email,nickname:username', ~~~ 表示關聯表的nickname字段映射成當前數據對象的username字段。 默認會把所有定義的關聯數據都查詢出來,有時候我們并不希望這樣,就可以給relation方法傳入參數來控制要關聯查詢的。 ~~~ $User = D("User"); $user = $User->relation('Profile')->find(1); ~~~ 關聯查詢一樣可以支持select方法,如果要查詢多個數據,并同時獲取相應的關聯數據,可以改成: ~~~ $User = D("User"); $list = $User->relation(true)->Select(); ~~~ 如果希望在完成的查詢基礎之上 再進行關聯數據的查詢,可以使用 ~~~ $User = D("User"); $user = $User->find(1); // 表示對當前查詢的數據對象進行關聯數據獲取 $profile = $User->relationGet("Profile"); ~~~ 事實上,除了當前的參考模型User外,其他的關聯模型是不需要創建的。 ## 關聯操作 除了關聯查詢外,系統也支持關聯數據的自動寫入、更新和刪除 ### 關聯寫入 ~~~ $User = D("User"); $data = array(); $data["account"] = "ThinkPHP"; $data["password"] = "123456"; $data["Profile"] = array( 'email' =>'liu21st@gmail.com', 'nickname' =>'流年', ); $result = $User->relation(true)->add($data); ~~~ 這樣就會自動寫入關聯的Profile數據。 同樣,可以使用參數來控制要關聯寫入的數據: ~~~ $result = $User->relation("Profile")->add($data); ~~~ > 當MANY_TO_MANY時,不建議使用關聯插入。 ### 關聯更新 數據的關聯更新和關聯寫入類似 ~~~ $User = D("User"); $data["account"] = "ThinkPHP"; $data["password"] = "123456"; $data["Profile"] = array( 'email' =>'liu21st@gmail.com', 'nickname' =>'流年', ); $result = $User-> relation(true)->where(array('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"); ~~~
                  <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>

                              哎呀哎呀视频在线观看