天天看點

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

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

資料庫表與資料

       就從資料庫表開始啦,因為這樣可能會更利于大家去了解。大家都知道資料庫多對多關系都是需要三張表來完成的,一張主表,一張關聯表,還有一張中間表。比如我們這裡主表是學生表關聯課程表。因為一個學生可以學多們課程,一門課程可以有多個學生來上課是以需要有一個中間表把他們關聯起來。現在我就把今天需要做測試的幾張表都貼出來,也友善大家在有不明白的時候可以拿來做測試。

下面這張是學生表:

/*學生表*/

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

/* 表資料 */
insert into pwn_student(name,age,`class`,address) values('學生A',,'二班','a路2号');
insert into pwn_student(name,age,`class`,address) values('學生B',,'二班','a路1号');
insert into pwn_student(name,age,`class`,address) values('學生C',,'二班','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= DEFAULT CHARSET=utf8;

/*表資料*/
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
insert into pwn_Stu_cour(stu_id,cour_id) values(,);
           

學生課程表

/*學生課程表*/
DROP TABLE IF EXISTS `pwn_Course`;
CREATE TABLE `pwn_Course`(
`id` INT AUTO_INCREMENT NOT NULL,
`name` VARCHAR() NOT NULL DEFAULT '',
PRIMARY KEY(id)
)ENGINE=MyISAM AUTO_INCREMENT= 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 表新增之前的資料:

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

這下面是中間表新增前的資料:

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

好現在重新整理執行以下控制器看看效果,如果你的浏覽器裡顯示成功并且沒有任何報錯就表示成功:

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

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

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

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

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

我們看到資料不僅是添加進去了!而且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 '新增成功';
       }
    }

}
?>
           

好了,接下來我們重新整理一下看看浏覽器是不是顯示新增成功了。

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

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

然後‘學生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 '取消成功';
       }
    }

}
?>
           

下面看看重新整理結果:

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

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

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

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

關聯查詢

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

<?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=;$i<count($student->Course);$i++){
            var_dump($student->Course[$i]->toArray());
        }

    }

}
?>
           

上面這個是關聯查詢,因為擷取到的是資料集需要循環轉數組在輸出才看的更清楚些。

下面是查詢結果:

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

     雖然隻有一條新增的資料是不一樣的,但是查詢結果卻是正确的。這是我插入資料的時候沒有注意到的小細節,插入的時候一個學生連續好幾節課都在學一個課程。不過沒關系,因為我們隻是在做測試隻要測試的結果是正确的就ok了。

為了證明搜尋結果是正确的我把 pwn_Stu_cour 中間表的資料截圖上來,也友善了解一些。

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

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

點選這裡了解更多關于thinkphp5多對多關聯模型