Laravel ORM用法筆記
ORM簡單介紹
在Laravel中,ORM的主要工具是Eloquent。Eloquent提供了一種直覺式的方法來操作資料庫,讓資料表和模型之間建立了一對一或一對多的映射關係。以下是一些ORM操作的基本用法。
ORM資料種類
Laravel撈資料幾種類型:
- ORM:Eloquent 模型,可以$data->$field和$data[$field],有getter,setter
- QueryBuilder:關連數組(ArrayAccess),只能$data->$field,也有getter,setter(僅限一維以下才有,因為是stdClass)
Laravel兩種常用特別的資料格式:
- Collection: Laravel內建物件,有很多內建用法,但是存取資料基本上以陣列索引訪問為主
1
2$a = ['a' => 123];
$a = collect($a); - StdClass: PHP原生的物件,簡單來說就是讓資料可以對象屬性訪問
1
2$a = ['a' => 123];
$a = (object) ($a);
- Collection: Laravel內建物件,有很多內建用法,但是存取資料基本上以陣列索引訪問為主
使用ORM基本觀念
- 使用create、update、fill(批量賦值)時,要先設定fillable(白名單)或guarded(黑名單),否則會無法寫入
1
2
3
4
5
6
7
8
9protected $fillable = [
'field1',
'field2',
];
protected $guarded = [
'field3',
'field4',
];
ORM常見用法
撈資料常用方法
where常用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52// 基本用法
$query->where('id', '1');
// 如果是多個條件,可以使用陣列表示
// 第一種寫法
$query->where([
['id', '1'],
['date', '<=', date("Y-m-d H:i:s")]
]);
// 第二種寫法
$query->where([
['id' => '1'],
['date' => '<=', date("Y-m-d H:i:s")]
]);
// 如果要把多個條件括號起來,需使用閉包
$query->where(function ($query) {
$query->where('created_at', '>=', date("Y-m-d H:i:s"))
->orWhereNull('created_at');
});
// 如果要多括號條件,可以使用陣列放閉包(可多個)
$query->where([
['id', '1'],
['date', '<=', date("Y-m-d H:i:s")],
function ($query) {
$query->where('created_at', '>=', date("Y-m-d H:i:s"))
->orWhereNull('created_at');
}
]);
// 一次撈出多筆資料
$query->whereIn('id', [1, 2, 3, 4]);
// 一次撈出多筆資料,例如:一次撈出id為1~10的資料
$query->whereBetween('id', [1, 10]);
// 一次撈出多筆資料,例如:一次撈出id不為1~10的資料
$query->whereNotBetween('id', [1, 10]);
// 一次撈出多筆資料,例如:一次撈出沒有created_at的資料
$query->whereNull('created_at');
// 一次撈出多筆資料,例如:一次撈出有created_at的資料
$query->whereNotNull('created_at');
// 一次撈出多筆資料,例如:一次撈出有關聯資料的資料
$query->whereHas('comments');
// 一次撈出多筆資料,例如:一次撈出沒有關聯資料的資料
$query->whereDoesntHave('comments');其餘方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49// 只撈出特定欄位
$resource = $query->select('id');
// 沒有限制撈取欄位,只影響取出資料的格式
$resource = $query->pluck('id');
// 只撈出資料筆數
$resource = $query->count();
// 只撈出是否有資料
$resource = $query->exists();
// 只撈出特定欄位的最大值
$resource = $query->max('id');
// 只撈出特定欄位的最小值
$resource = $query->min('id');
// 只撈出特定欄位的平均值
$resource = $query->avg('id');
// 可將資料轉為QueryBuilder
$resource = $query->toBase();
// 可將資料分批撈出
$query->chunk(100, function ($resource) {
foreach ($resource as $value) {
// do something
}
});
// 可在操作資料時,做額外的動作
$query->tap(function ($query) use ($request) {
if ($request->has('search') && $request->search != '') {
$query->where('title', 'like', '%' . $request->search . '%');
}
});
// 可拿到與comments關聯的post資料
$posts = App\Post::has('comments')->get();
// 跟上面不同的是,這個是拿到comments資料
$comments = $post->comments;
// 可拿到與comments沒有關聯的post資料
$posts = App\Post::doesntHave('comments')->get();
// 與doesntHave很像,但是這可以使用where條件(第二參數也可帶閉包)
$resource = $query->whereDoesntHave('comments');善用with,可以一次撈出多筆資料,例如:一次撈出user、profile、posts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 這樣寫會有N+1問題
$users = User::all();
foreach ($users as $user) {
echo $user->profile->name;
echo $user->posts->title;
}
// 這樣寫就不會有N+1問題
$users = User::with(['profile', 'posts'])->get();
foreach ($users as $user) {
echo $user->profile->name;
echo $user->posts->title;
}
# with其他用法
// 一次撈出多個關聯資料
$query->with(['data', 'data2']);
// 一次撈出多個關聯資料(包含軟刪除資料)
$query->withTrashed(['data', 'data2']);
CUD常用方法
create、update、delete常用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 基本用法
$model->create([
'field1' => 'value1',
'field2' => 'value2',
]);
// 基本用法
$model->update([
'field1' => 'value1',
'field2' => 'value2',
]);
// 基本用法
$model->delete();
// 基本用法
$model->forceDelete();
// 基本用法
$model->restore();假捨想要無視批量賦值的限制,可以使用forceFill、forceCreate、forceUpdate
1
2
3
4
5
6
7
8
9
10
11
12
13
14$model->forceFill([
'field1' => 'value1',
'field2' => 'value2',
]);
$model->forceCreate([
'field1' => 'value1',
'field2' => 'value2',
]);
$model->forceUpdate([
'field1' => 'value1',
'field2' => 'value2',
]);複製資料
1
2
3
4
5// 基本用法
$model->replicate();
// 基本用法
$model->replicate()->save();使用create、update、delete時,會自動更新updated_at欄位,如果不想要更新,可以使用updateTimestamps(),但是要注意,這個方法會把created_at、updated_at都設為null
1
2$model->updateTimestamps();
$model->save();
其餘常用方法
- 要把撈出的資料刪除,一樣使用迴圈unset
1
2
3foreach ($resource as $key => $value) {
unset($resource[$key]);
}
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment