一對一模型關(guān)聯(lián)
1. 前言
本小節(jié)介紹如何使用模型關(guān)聯(lián),當(dāng)你需要使用多表聯(lián)合查詢數(shù)據(jù)的時(shí)候,若使用模型關(guān)聯(lián)可以讓代碼變得更簡潔,一對一模型關(guān)聯(lián)主要針對的是兩個(gè)表中的數(shù)據(jù)只有一對一的關(guān)系,或者只需要取出一對一關(guān)系的數(shù)據(jù)。
2. 添加測試數(shù)據(jù)
這里為了演示方便,需要向之前新建好的 課程表(course)
、教師表(teacher)
添加數(shù)據(jù),添加教師表數(shù)據(jù) SQL
如下:
如下圖所示:
添加課程表數(shù)據(jù) SQL
語句如下:
如下圖所示:
3. 接口路由定義
這里以查詢課程表(course)
數(shù)據(jù)為例,通過一對一
模型關(guān)聯(lián)出課程表對應(yīng)的教師信息:
Route::get('courses','app\controller\Study\CourseController@courseList');
如下圖所示:
4. 控制器和方法定義
下面貼出路由中定義的控制器和查詢方法:
<?php
namespace app\controller\Study;
use app\BaseController;
use app\Models\Study\CourseModel;
class CourseController extends BaseController
{
/**
* 獲取教師列表
*/
public function courseList()
{
$size = (int)$this->request->param('size', 15);
$students = CourseModel::where('status', 1)->order('created_at DESC')->paginate($size);
return json($students);
}
}
如下圖所示:
5. 請求課程列表接口數(shù)據(jù)
下面使用 postman
請求接口數(shù)據(jù)如下:
{
"total": 6,
"per_page": 10,
"current_page": 1,
"last_page": 1,
"data": [
{
"id": 1,
"course_name": "廣義相對論",
"teacher_id": 1,
"created_at": 1603617951,
"update_at": 0,
"status": 1
},
{
"id": 2,
"course_name": "電動力學(xué)",
"teacher_id": 2,
"created_at": 1603617951,
"update_at": 0,
"status": 1
},
{
"id": 3,
"course_name": "電磁學(xué)",
"teacher_id": 3,
"created_at": 1603617951,
"update_at": 0,
"status": 1
},
{
"id": 4,
"course_name": "光學(xué)",
"teacher_id": 4,
"created_at": 1603617951,
"update_at": 0,
"status": 1
},
{
"id": 5,
"course_name": "信息論",
"teacher_id": 5,
"created_at": 1603617951,
"update_at": 0,
"status": 1
},
{
"id": 6,
"course_name": "天文學(xué)",
"teacher_id": 6,
"created_at": 1603617951,
"update_at": 0,
"status": 1
}
]
}
如下圖所示:
6. 設(shè)置模型關(guān)聯(lián)方法
若要在課程列表數(shù)據(jù)中關(guān)聯(lián)出教師信息可以在 CourseModel
模型中使用如下 teacher
方法:
<?php
namespace app\Models\Study;
use think\Model;
class CourseModel extends Model
{
protected $table = 'course';
/**
* 一對一模型關(guān)聯(lián)
*/
public function teacher()
{
return $this->hasOne(TeacherModel::class, "id", "teacher_id");
}
}
如下圖所示:
7. 使用 with 預(yù)加載出關(guān)聯(lián)信息
可以在課程列表接口的方法中使用 with()
方法預(yù)加載出關(guān)聯(lián)信息:
$students = CourseModel::where('status', 1)
->with('teacher')
->order('created_at DESC')
->paginate($size);
Tips: 其中
with('teacher')
預(yù)加載出teacher
屬性,也可以不使用with
被動加載出teacher
,如調(diào)用$studentModel->teacher
的時(shí)候,若模型不存在teacher
屬性,會觸發(fā)模型關(guān)聯(lián)同名
的方法。
8. 請求模型關(guān)聯(lián)之后的數(shù)據(jù)
下面使用 postman
請求接口部分?jǐn)?shù)據(jù)如下:
{
"id": 1,
"course_name": "廣義相對論",
"teacher_id": 1,
"created_at": 1603617951,
"update_at": 0,
"status": 1,
"teacher": {
"id": 1,
"name": "愛老師",
"age": 24,
"id_number": "52011720100506XXXX",
"created_at": 1603617951,
"update_at": 0,
"status": 1
}
}
Tips: 此時(shí)列表中出現(xiàn)了
teacher
屬性字段,這個(gè)字段就是課程列表一對一關(guān)聯(lián)出來的教師信息。
9. 小結(jié)
本小節(jié)主要介紹如何使用模型關(guān)聯(lián)一對一的方式,在查詢課程列表的時(shí)候關(guān)聯(lián)出教師信息,這樣就不必書寫繁瑣的連表查詢邏輯。
需要注意的是,一般情況下使用模型關(guān)聯(lián)最好使用 with
預(yù)加載出來,預(yù)加載列表信息底層實(shí)際使用的是 IN
查詢一次全部查出列表內(nèi)容,若在列表中被動觸發(fā)可能會造成多次查詢帶來的性能問題。
Tips: 代碼倉庫:https://gitee.com/love-for-poetry/tp6