Thinkphp5關聯模型的定義與使用

定義一對一關聯

這裏假設你已經把thinkphp5的環境都配置好了,數據庫也連接OK了。想通過模型把兩張表關聯起來然後在通過控制器一調用就可以得到兩張表的信息。
現在我準備了兩張表,一張管理員表pwn_admin一張管理員信息表pwn_admin_message 爲了能更方便的理解我把兩張表的表結構也貼出來了。
下面是兩張表的表結構信息:

CREATE TABLE `pwn_admin` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `user` varchar(30) NOT NULL DEFAULT '',
  `password` varchar(50) NOT NULL DEFAULT '',
  `name` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
CREATE TABLE `pwn_admin_message` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `email` varchar(30) NOT NULL DEFAULT '',
  `mobile` varchar(50) NOT NULL DEFAULT '',
  `aid` int(11) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

建模型文件

接下來是新建對應兩張數據表的模型類文件。在模塊下新建一個model目錄然後新建兩個文件並按對應的表命名:
這裏寫圖片描述

模型命名

模型類的命名規則是除去表前綴的數據表名稱,採用駝峯法命名,並且首字母大寫,比如上面兩張表的表前綴是pwn_ 在模型名稱裏就需要省略掉。所以pwn_admin 表的模型類名就是 Adminpwn_admin_message 的模型類名就是AdminMessage

hasOne方法的參數包括:

hasOne(‘關聯模型名’,’外鍵名’,’主鍵名’,[‘模型別名定義’],’join類型’);

默認的join類型爲INNER

模型定義

Admin模型對應的是 pwn_admin 表

<?php
namespace app\index\model;

use think\Model;
class Admin extends Model{

    function AdminMessage(){
        //aid爲外鍵id是adminmessage表關聯admin表的外鍵
        //id是 admin表的主鍵
        return $this->hasOne('AdminMessage','aid','id')->field('id,coltype,auth,name,intro,xuhao,pid,pname');
    }
}


?>

在Admin模型定義好關聯的方法之後在AdminMessage模型裏可以不用寫任何對應的方法,但是必須最少要有一個對應 pwn_admin_message 表的空模型。
相應的如果在這個模型裏寫了

<?php
namespace app\index\model;

use think\Model;
class AdminMessage extends Model{


}
?>

有一點需要注意的是,關聯方法的命名規範是駝峯法,而關聯屬性則一般是小寫+下劃線的方式,系統在獲取的時候會自動轉換對應,讀取user_profile關聯屬性則對應的關聯方法應該是userProfile。

控制器調用

在控制器想要使用關聯模型就需要先引入模型類,比如我上面是在admin模型裏定義了關聯的方法,就需要把admin模型引入控制器。

use app\index\model\Admin

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class Index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
        //get 1 是獲取id爲 1 的數據
        //find() 是查找
        //toArray()  是獲取到的數據轉爲數組
       $admin= Admin::get(1);
    var_dump($admin->find()->toArray());
    }
    ?>

好啦下面就可以訪問以下瀏覽器看看結果了。

這裏寫圖片描述

如果你的結果是這樣只有admin管理員表的數據,彆着急這是正常的。如果想要獲取到關聯表pwn_admin_message 的數據就需要先調用剛纔定義的 AdminMessage() 模型方法,然後在指向find()方法取出數據。
注意:
這個find()方法是不可以省略掉的哦,我就是因爲這個方法沒加上所以一直不能取出完整的管理員信息。

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
       $admin= Admin::get(1);
       //查詢出pwn_admin_message 表aid爲 1 的一條數據,然後轉數組。
       $admin= $admin->AdminMessage->find()->toArray();  
        var_dump($admin);
        }
    }
  ?>

得到的結果是

這裏寫圖片描述

因爲是測試爲了方便我就不用數字號碼了,直接用文字代號這樣比較直觀明瞭。

hasWhere()方法:

如果要根據關聯表的查詢條件查詢當前模型的數據,可以使用hasWhere方法,例如:
<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
        $admin=Admin::hasWhere('AdminMessage',['email'=>'[email protected]']);
        $admin=$admin->find()->toArray();
        var_dump($admin);
    }
   }
    ?>

輸出結果:

這裏寫圖片描述

定義一對多關聯

一對多的關聯和一對一的關聯的使用差不多都是一樣的,區別是方法名不同。一對多在模型裏使用的方法名是 hasMany 。hasMany 和 hasOne 的使用方法和參數基本相同。

hasMany參數是:

hasMany(‘關聯模型名’,’外鍵名’,’主鍵名’,[‘模型別名定義’]);

還是以上面兩張表爲例,但是爲了配合一對多關聯 pwn_admin_message 的內容還有aid 字段需要稍微修改一下。改成一個管理員有多個手機號,有多個email郵箱。
爲了方便理解我把兩張表的數據內容截圖上來。
下圖是 pwn_admin_message 表的內容:
這裏寫圖片描述

下圖是 pwn_admin 表的內容:

這裏寫圖片描述

有幾個管理員沒有數據,不過沒關係足夠測試就可以了。好了廢話不多說,開始進入正題。
相信大家一看就知道下面這個是admin模型的內容,對應的是pwd_admin 表

 <?php
namespace app\index\model;

use think\Model;
class Admin extends Model{

 public   function AdminMessage(){
        //pid爲外鍵id是adminmessage表關聯admin表的外鍵
        //id是 admin表的主鍵
        return $this->hasMany('AdminMessage','aid','id');
    }
}

而這下面這個是 AdminMessage 對應的是哪張表我就不說了。這和一對一關聯一樣也可以是個空模型

<?php
namespace app\index\model;
use think\Model;

class AdminMessage extends Model{
    /*    
    function Admin(){
      return $this->belongsTo('Admin','aid','id');
    }
    */
}
?>

控制器調用,這回就有點不一樣了。因爲返回的數據是一個二維數組裏麪包含了多個對象所以需要把數組循環出來並把對象在轉爲數組才能輸出

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
       $admin= Admin::get(1);
       //查找出 pwn_admin_message 表關聯aid爲1是所有數據
       $admin= $admin->AdminMessage()->select();
        for($i=0;$i<count($admin);$i++){
            var_dump($admin[$i]->toArray());
        }
    }
}
?>

輸出結果:

這裏寫圖片描述

還有兩個函數也順便說一下了,一個是 hasWhere 還有一個 has 這兩個都是根據關聯條件來查詢的,通俗點講就是根據關聯到 pwd_admin 表,的 pwn_admin_message 表字段的條件來查詢的。如果換過來用pwd_admin裏的字段作爲條件查詢的話就會報錯。

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
     //  $admin= Admin::get(1);
     $list= Admin::hasWhere('AdminMessage',['aid'=>1])->select();
     $list1=Admin::has('AdminMessage',['aid'=>2])->select();
    var_dump($list1[0]->toArray());
    }
   }

   ?>

這樣子關聯得出的結果是正常的:

這裏寫圖片描述

如果按 pwd_admin 表的字段做爲搜索條件就會報錯。比如我用一個 pwn_admin_message 沒有的字段,用user字段來做爲條件查詢試試。

<?php
namespace app\index\controller;
use think\Controller;
use app\index\model\Admin;

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
     //  $admin= Admin::get(1);
    // $list= Admin::hasWhere('AdminMessage',['aid'=>1])->select();
     $list1=Admin::has('AdminMessage',['user'=>'jiehechen123'])->select();
     var_dump($list1[0]->toArray());
    }
   }
  ?>

就好報出如下錯誤:
這裏寫圖片描述

好了我這裏就講這麼多了,這篇文章主要講一對一和一對多的幾個常用使用使用方法而已,其他的還有好多方法的用法可以參考手冊。我已經盡力的講的很細瞭如果有不明白或是有什麼寶貴意見的歡迎留言。

想要了解更多關關於聯模型一對一一對多請點擊這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章