查不到数据主因是模型未对表、查询未终结或字段未选取;需显式声明表名、主键及类型,链式调用后必加get()/first()等终结方法,慎用字符串时间查询,预加载防n+1,精简字段提升性能。

查不到数据,八成不是写错了语法,而是模型没对上表、查询没执行完、或者字段根本没取出来。
模型没指定表名或主键时会静默失败
Eloquent 默认按 User 类名推断表名为 users,主键为 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 根本没发出去。常见错误写法:User::where('id', 1)->get()->first(),这会先查全部再取第一个,浪费资源。
- 查单条:优先用
find($id)(仅限主键)或where(...)->first() - 查多条:用
get(),返回Collection - 只取某个字段值:用
value('email')或pluck('name'),避免构造完整模型
时间范围查询别硬写字符串,用 Carbon 构造边界
whereDate('created_at', '2024-05-01') 看似简单,但底层走 DATE() 函数,在有索引的字段上大概率失效;手写 '2024-05-01 00:00:00' 又容易格式错、时区错。
- 推荐用
whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()]) - 确保 PHP 时区和数据库时区一致,否则
now()生成的时间可能跨天 - 如果必须用字符串,统一用
Y-m-d H:i:s格式,并确认 MySQL 的sql_mode允许隐式转换
关联没加 with() 就直接循环访问,N+1 问题立马出现
写 foreach ($users as $u) { $u->profile; },Eloquent 不会合并查询——每个 $u->profile 都触发一次额外 SQL。
- 提前用
User::with('profile')->get()一次性预加载 - 嵌套关联如
posts.comments,写成with(['posts.comments' => function ($q) { $q->latest(); }]) - 别在循环里用
load(),它只是延迟加载,照样 N+1 - 不确定是否真合并了?用
toSql()检查:User::with('profile')->toSql()
最常被忽略的其实是字段选择和终结方法——find(1, ['id', 'name']) 和 first(['id', 'name']) 这种写法能省下大量不必要字段传输,而漏掉 get() 或 first() 则让整个查询停留在“准备状态”,连日志里都看不到 SQL。











