Laravel中如何使用Eloquent ORM查询数据_Laravel模型查询常用操作【深入】

9次阅读

查不到数据主因是模型配置错误或查询未终结;需显式声明表名、主键及类型,链式查询后必须调用get()/first()等终结方法,时间范围推荐用whereBetween配合carbon对象

Laravel中如何使用Eloquent ORM查询数据_Laravel模型查询常用操作【深入】

直接查不到数据,大概率不是语法写错,而是模型配置、查询上下文或数据库状态没对上。

模型没指定表名或主键会静默失败

Eloquent 默认按模型类名复数形式推断表名(Userusers),主键默认是 id。如果表名不规则(比如 user_info)或主键是 uid,不显式声明就会查空或报错。

  • 在模型中加 protected $table = 'user_info';
  • 主键非 id 时加 protected $primaryKey = 'uid';
  • 主键不是整型(如 UUID)必须加 public $incrementing = false;protected $keyType = 'String';

where() 链式调用后必须加 get()first()

User::where('status', 1) 返回的是 Builder 实例,不是结果集。不执行终结方法,sql 根本不会发出去。

  • 查多条:用 get() → 返回 Collection
  • 查单条:优先用 first()(带条件)或 find($id)(主键查找)
  • 只取字段:用 pluck('name')value('email'),避免构造完整模型实例
User::where('status', 1)->orderBy('created_at', 'desc')->take(5)->get();

时间范围查询慎用 wheredate()whereBetween()

wheredate('created_at', '2024-05-01') 会忽略时分秒,但底层走的是 DATE() 函数,在有索引的 created_at 字段上可能无法命中索引;而 whereBetween() 如果手写时间字符串格式不对(如缺 T00:00:00),mysql 可能自动类型转换失败。

  • 推荐用 whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()])
  • 或手动构造范围:where('created_at', '>=', '2024-05-01 00:00:00')->where('created_at', '
  • 确认数据库时区和 PHP 时区一致,否则 now() 生成的时间可能跨天

关联预加载没写 with() 就会 N+1

比如循环查用户再查其头像:foreach ($users as $u) { $u->avatar; },会为每个用户发起一次额外查询。Eloquent 不会自动合并。

  • 提前用 with('avatar') 一次性关联查出
  • 嵌套关联写成 with(['posts.comments' => function ($q) { $q->latest(); }])
  • 避免 load() 在循环里调用——它只是延迟加载,照样 N+1
  • toSql() 检查生成的 SQL:User::with('profile')->toSql() 看是否真合并了
User::with(['posts' => function ($q) {     $q->where('published', true)->limit(3); }])->get();

最常被忽略的是模型的 $casts 和访问器(accessor)对查询结果的影响:它们只作用于已查出的数据,不影响 WHERE 条件;想按 JSON 字段某个键过滤,得用 whereJsonContains(),不能靠 cast 后的属性名去 where。

text=ZqhQzanResources