Thinkphp5關聯模型多對多的定義與使用

       想了想我還是覺得在寫一篇關於多對多的文檔吧,因爲我看了官方的文檔寫的不夠細,不好理解。我自己也花了時間去看人家的文檔還有自己又做了一些測試才知道怎麼用的現在把我做測試的所有過程分享給大家。

數據庫表與數據

       就從數據庫表開始啦,因爲這樣可能會更利於大家去理解。大家都知道數據庫多對多關係都是需要三張表來完成的,一張主表,一張關聯表,還有一張中間表。比如我們這裏主表是學生表關聯課程表。因爲一個學生可以學多們課程,一門課程可以有多個學生來上課所以需要有一箇中間表把他們關聯起來。現在我就把今天需要做測試的幾張表都貼出來,也方便大家在有不明白的時候可以拿來做測試。

下面這張是學生表:


  /*學生表*/

DROP TABLE IF EXISTS `pwn_student`;
CREATE TABLE pwn_student (
id INT AUTO_INCREMENT,
name VARCHAR(30),
age INT ,
class VARCHAR(50),
address VARCHAR(100),
PRIMARY KEY(id)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

/* 表數據 */
insert into pwn_student(name,age,`class`,address) values('學生A',15,'二班','a路2號');
insert into pwn_student(name,age,`class`,address) values('學生B',16,'二班','a路1號');
insert into pwn_student(name,age,`class`,address) values('學生C',15,'二班','B路1號');

中間表:

/*學生課程關聯表*/
DROP TABLE IF EXISTS `pwn_Stu_Cour`;
CREATE TABLE pwn_Stu_Cour(
id INT AUTO_INCREMENT,
stu_id INT ,
cour_id INT,
PRIMARY KEY(id)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

/*表數據*/
insert into pwn_Stu_cour(stu_id,cour_id) values(1,1);
insert into pwn_Stu_cour(stu_id,cour_id) values(2,2);
insert into pwn_Stu_cour(stu_id,cour_id) values(3,3);
insert into pwn_Stu_cour(stu_id,cour_id) values(1,1);
insert into pwn_Stu_cour(stu_id,cour_id) values(2,2);
insert into pwn_Stu_cour(stu_id,cour_id) values(3,3);
insert into pwn_Stu_cour(stu_id,cour_id) values(1,1);
insert into pwn_Stu_cour(stu_id,cour_id) values(2,2);
insert into pwn_Stu_cour(stu_id,cour_id) values(3,3);
insert into pwn_Stu_cour(stu_id,cour_id) values(1,1);
insert into pwn_Stu_cour(stu_id,cour_id) values(2,2);
insert into pwn_Stu_cour(stu_id,cour_id) values(3,3);

學生課程表

/*學生課程表*/
DROP TABLE IF EXISTS `pwn_Course`;
CREATE TABLE `pwn_Course`(
`id` INT AUTO_INCREMENT NOT NULL,
`name` VARCHAR(150) NOT NULL DEFAULT '',
PRIMARY KEY(id)
)ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

/*表數據*/

insert into `pwn_course`(name) values('數學');
insert into `pwn_course`(name) values('語文');
insert into `pwn_course`(name) values('物理');
insert into `pwn_course`(name) values('化學');
insert into `pwn_course`(name) values('生物');
insert into `pwn_course`(name) values('英語');

如果有對數據庫多對多關係有不明白的大家可以到網上去搜索一下因爲今天主要講的是TP5的關聯模型,如果mysql也講的話就內容太多了。

創建模型

      在模型開始創建之前先給大家介紹一個方法,是thinkphp5關聯模型多對多中需要使用到的方法 belongsToMany 方法。

belongsToMany方法的參數如下:

belongsToMany(‘關聯模型名’,’中間表名’,’外鍵名’,’當前模型關聯鍵名’,[‘模型別名定義’]);

關聯模型名:
      是指當前模型需要關聯的其他模型,比如我們的當前模型是Student 摸行,去關聯 Course 模型,那關聯模型就需要填course。

中間表名:
      這個就不用說了,就是中間表名不用寫前綴

外鍵名:
      是中間表 pwn_Stu_Cour 關聯 course 表的外鍵id。

當前模型關聯鍵名:
      是中間表 pwn_Stu_Cour 關聯 student 表的關聯鍵名。

      現在一切都準備好了之後接下來就進入今天的主題,創建tp模型。一般情況下一張表需要對應創建一個模型,但是多對多的關係裏中間表的模型可以省略掉。也就是說我們只要創建學生表模型 Student 和課程表模型就可以了。

下面是Student模型

<?php
namespace app\index\model;
use think\Model;
class Student extends Model{

 public   function Course(){
        //cour_id是關聯中間表的關聯course表的外鍵id,而stu_id也是中間表關聯學生表的外鍵id
        //兩個id都是中間表關聯其他表的外鍵id
        //這個大家應該一看就知道都是中間表的id,因爲在`pwn_student` 學生表和`pwn_Course`課程表裏沒有這兩個字段。 
        return $this->belongsToMany('course','stu_cour','cour_id','stu_id');
    }
}

?>

這個模型上面 belongsToMany() 方法的參數什麼相信大家都已經知道了吧,如果不知道的話回頭到上面去看一下。

下面這個是 Course 模型

<?php
namespace app\index\model;
use think\Model;
class Course extends Model{
    function Student(){
    //  return $this->belongsTo('Admin','aid','id');
      //  return $this->belongsToMany('student','stu_cour','cour_id','stu_id');

    }

}

?>

這個Course模型可以是空的不寫任何方法但是不能沒有不然會報錯

控制器調用:

關聯新增

控制器調用模型和其他調用方法一樣也是先用命名空間把他引入控制器然後調用
use app\index\model\Student;

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

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
    //這的意思是從 pwn_student 學生表的name字段中取出'學生A'的信息
     $student=Student::getByName('學生A');
     //給關聯表 pwn_course 新增一條 name 數據
    $res= $student->Course()->save(['name'=>'地理']);
    if($res){
        echo "新增成功";
    }
  }
}
?>

這樣在 pwn_course 表裏新增一條數在中間表裏也會自動生成有對應關聯id的數據,只要在模型中把中間表關聯的id位置寫對。

這是 pwn_course 表新增之前的數據:

這裏寫圖片描述

這下面是中間表新增前的數據:

這裏寫圖片描述

好現在刷新執行以下控制器看看效果,如果你的瀏覽器裏顯示成功並且沒有任何報錯就表示成功:

這裏寫圖片描述

這是我的執行結果,我們看到它已經新增成功了。接下來看看數據庫是不是也是成功了。

這裏寫圖片描述

從圖上可以看出我們新增的數據已經添加到了數據表裏了。表示在這張表上面是沒有問題的已經把數據添加上去了,但是我們還有一張把學生表和課程表關聯起來很重要的中間表是否也添加成功了呢?接下來讓我們到 pwn_Stu_Cour 中間表去看一下。
這裏寫圖片描述

我們看到數據不僅是添加進去了!而且id都已經對號入座說明我們已經成功。

新增中間表數據

     比如我們想給‘學生A’新增一門語文課。這個時候我們就需要添加中間表來完成新增‘學生A’的課程。還有一個是我們需要用模型 Course 來獲取課程信息所以這個時候 Course 表就不能是空的了。他需要關聯 Student 模型,關聯的方法和 Student 一樣。

下面是 Course 模型:

<?php
namespace app\index\model;
use think\Model;
class Course extends Model{
    function Student(){
    //  return $this->belongsTo('Admin','aid','id');
        return $this->belongsToMany('student','stu_cour','stu_id','cour_id');

    }
}

?>

因爲所有的方法參數都是和 Studen 模型是一樣的所以我這裏就不多介紹了。

下面是控制器方法:

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

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
        //獲取學生A的所有數據
        $student = Student::getByName('學生A');   //獲取學生A是信息
        $course=Course::getByName('語文'); //獲取語文信息
       $res= $student->Course()->attach($course);  //給中間表插入數據
       if($res){
           echo '新增成功';
       }
    }

}
?>

好了,接下來我們刷新一下看看瀏覽器是不是顯示新增成功了。

這裏寫圖片描述

這裏寫圖片描述

我們看到上圖說明已經新增成功了。

然後‘學生A’的課程多了一些可能忙不過來,需要取消掉一些課程也是可以的。

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

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
        //獲取學生A的所有數據
        $student = Student::getByName('學生A');
        $course=Course::getByName('地理');
       $res= $student->Course()->detach($course);
       if($res){
           echo '取消成功';
       }
    }

}
?>

下面看看刷新結果:
這裏寫圖片描述

開始的時候我看到這個以爲是失敗了,但是看看數據庫’學生A’中間裏的地理課程確實已經沒有了。以爲是哪裏出錯了就重新檢查了一遍隨便修改了’學生A’的課程在試一次發現瀏覽器上顯示的還是一樣的結果,數據庫那條記錄也還是又一次被刪除了。具體原因現在還不清楚,不想深究了因爲現在太晚了。請多多包涵哈,明天還要上班呢!

下面是數據庫的所有記錄,那條’學生A’的地理課程記錄已經不在了。

這裏寫圖片描述

關聯查詢

     只要大家掌握好了上面的基本操作接下來的關聯查詢都會非常簡單,我會盡量截圖把每一個細節都截下來讓大家看到。

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

class index extends Controller
{
    /**
     * @param string $name
     */
    public function index($name='name')
    {
        //獲取學生A的所有數據
        $student=Student::getByName('學生A');
       //因爲獲取到的數據都是數組裏包含對象所以需要循環出數組裏的對象在把每一個對象轉爲數組在輸出
        for($i=0;$i<count($student->Course);$i++){
            var_dump($student->Course[$i]->toArray());
        }

    }

}
?>

上面這個是關聯查詢,因爲獲取到的是數據集需要循環轉數組在輸出纔看的更清楚些。
下面是查詢結果:
這裏寫圖片描述

     雖然只有一條新增的數據是不一樣的,但是查詢結果卻是正確的。這是我插入數據的時候沒有注意到的小細節,插入的時候一個學生連續好幾節課都在學一個課程。不過沒關係,因爲我們只是在做測試只要測試的結果是正確的就ok了。
爲了證明搜索結果是正確的我把 pwn_Stu_cour 中間表的數據截圖上來,也方便理解一些。
這裏寫圖片描述

我這裏就介紹了幾個查找,添加,刪除的方法,目的是爲了介紹更詳細的使用流程,但不會每一個都介紹過去。那樣子太耗時間了,也沒必要。因爲手冊上已經都講的很清楚了。

點擊這裏瞭解更多關於thinkphp5多對多關聯模型

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