目录
一. DB门面(查询构建器)
1.查询实例
查询实例对象解析:
返回的实例对象为Illuminate\Database\Query\Builder
$result = DB::table("表名");
// 打印$result结果
Illuminate\Database\Query\Builder {
...
}
切换多数据库:
可使用connection()
方法选择指定的数据库,返回实例也为 Illuminate\Database\Query\Builder
,因为此调用first()
或get()
等方法得到的结果与直接使用DB::table("表名")调用一样;
$result = DB::connection('数据库连接别名')->table("表名");
// 打印$result结果
Illuminate\Database\Query\Builder {
}
2. 常用查询方法
get()方法详解
-
返回数据类型:
结果集是一个Illuminate\Support\Collection
对象实例, 其中每个子项都是实际上是PHP StdClass
对象的一个实例// 查询方法 $data = DB::table('user')->whereIn('id', [1,2])->get(); // 取值结果 foreach($data as $da) { $userId = $da->id; // 子项都是对象,只能采用对象取值 }
有值返回的打印结果
Illuminate\Support\Collection^ {#2184 #items: array:2 [ 0 => {#2195 +"id": 1 } 1 => {#2186 +"id": 2 } ] }
无值返回的结果
Illuminate\Support\Collection^ {#2184 #items: [] }
-
空结果判断:
可以通过isEmpty()
方法判断是否存在数据对象, 存在为false, 不存在为true -
结果集转化为二维数组:
❌ 错误方式: 使用get()->toArray()
, 会得到一个数组,但数组子元素还是StdClass对象的实例, 查询无结果时为空数组;# 返回值 array:2 [ 0 => {#2195 +"id": 1 } 1 => {#2186 +"id": 2 } ]
$data = DB::table('user')->select(['id'])->get()->toArray(); // 因此只能用对象取值法 foreach ($data as $da) { $userId = $da->id; }
✅ 正确方式: 可采用
map()
方法,将数据子项对象强制转化为数组。$data = DB::table('user')->select(['id'])->get()->map(function($item) { return (array)$item; })->toArray(); // 数组可直接使用empty()判断是否有数据 if (empty($data)) { return "暂无数据"; } foreach ($data as $da) { $userId = $da['id']; // 采用数组方式取值,无法通过对象取值了 }
first()方法详解
-
返回数据类型:
查询有结果时,返回一个StdClass对象实例;查询无结果时返回null;$info = DB::table('user')->where('id', 1)->first();
# 返回值结果 {#2197 +"id": 1 +"name": "demo" }
-
空结果判断:
可以通过empty()
方法判断是否存在数据对象, 存在为false, 不存在为true -
转化为二维数组: 可以通过
->toArray()
转化,先判断是否为空再进行转化,否则会报错$data = User::where('id', 1)->first(); $data = $data ? $data->toArray() : [];
-
变形语法:
简写化写法find()
,find(1)
等价于->where('id',1)->first()
二. Eloquent ORM(模型查询)
1. 查询实例
查询实例对象解析:
返回的实例对象为Illuminate\Database\Eloquent\Builder
$result = User::query();
// 打印result结果
Illuminate\Database\Eloquent\Builder^ {#2188
...
}
两种语法:
// 常用写法
$result = User::where('id', 1);
// 等价于上面的语法,返回实例相同,是上面语法的完整版
$result = User::query()->where('id', 1);
切换多数据库:
通过模型类中$connection
属性来控制数据库切换
2. 常用查询方法
get()方法详解
-
返回数据类型:
结果集是一个Illuminate\Database\Eloquent\Collection
对象,其子项是模型对象实例,例如 App\Model\User// 查询方法 $data = User::whereIn('id', [1, 2])->get(); // 取值结果 (数组或对象取值都可以) foreach ($data as $da) { $userId = $da->id; $userName = $da['name']; }
有值返回的打印结果
Illuminate\Database\Eloquent\Collection^ {#2203 #items: array:2 [ 0 => App\Model\User^ {#2204 #table: "user" #guarded: [] +timestamps: false #connection: "mysql" #primaryKey: "id" #keyType: "int" +incrementing: true #with: [] #withCount: [] #perPage: 15 +exists: true +wasRecentlyCreated: false #attributes: array:24 [ "id" => 1 "name" => "测试" ] #original: array:24 [ "id" => 1 "name" => "测试" ] #changes: [] #casts: [] #dates: [] #dateFormat: null #appends: [] #dispatchesEvents: [] #observables: [] #relations: [] #touches: [] #hidden: [] #visible: [] #fillable: [] } ] }
-
空结果判断 可以通过
isEmpty()
方法判断是否存在数据对象, 存在为false, 不存在为true -
结果转化为二维数组 使用
get()->toArray()
,有值返回的标准的二维数组,无值返回空数组
first()方法详解
- 返回数据类型:
查询有结果时,返回一个模型对象实例; 查询无结果时返回null; - 空结果判断
可以通过
empty()
方法判断是否存在数据对象, 存在为false, 不存在为true - 转化为二维数组:
可以通过
->toArray()
转化,先判断是否为空再进行转化,否则会报错$data = User::where('id', 1)->first(); $data = $data ? $data->toArray() : [];
三. 两者的区别和避坑点
1. DB门面和与模型查询实例的关联和区别
对比关系
维度 | DB门面 | 模型Eloquent |
---|---|---|
返回实例 | Illuminate\Database\Query\Builder | Illuminate\Database\Eloquent\Builder |
内存占用 | 较低(StdClass对象) | 较高(模型对象) |
查询复杂度 | 适合简单查询 | 支持复杂模型关联 |
2. 典型报错场景与解决方案
问题: 模型类取实例属性时例如已设置的分组字段groups 会出现报错 Exception: Property [groups] does not exist on the Eloquent builder instance
- 原因: 模型类是基于查询构造器实例的基础上封装,它无法直接获取查询构造器中的属性
- 解决方法: 通过调用
getQuery()
,获取基础的查询构造器实例,然后再获取属性。从而获取关键属性信息如分组字段groups
、查询字段columns
、排序字段orders
$builder = User::query();
// 会报错
$builder->groups;
// 正确做法, 此时会调用查询构造器实例
$builder->getQuery()->groups;