查不到数据时应先用DB::enableQueryLog()和DB::getQueryLog()查看实际SQL及参数,注意toSql()须在执行前调用;检查字段类型匹配、软删除状态、外键配置及时间条件是否合理。

查不到数据时先看生成的 SQL 是什么
直接在查询后加 toSql() 能看到 Eloquent 实际执行的语句,但注意它不带参数值,只显示占位符。更实用的是用 Laravel 的查询日志:DB::enableQueryLog() + DB::getQueryLog(),配合 dd() 查看最后一条记录。记得只在本地或调试环境开,线上别留着。
常见陷阱:调用 toSql() 时如果用了 get() 或 first() 之后再调,会报错——toSql() 必须在执行前调用,比如:User::where('id', 1)->toSql() 可以,User::where('id', 1)->get()->toSql() 不行。
检查 where 条件里的字段名和数据类型是否匹配
Laravel 不会主动帮你转换类型,比如数据库里 status 是 tinyint(1),你传字符串 '1' 进去,MySQL 在严格模式下可能不匹配。尤其注意布尔字段、枚举、时间戳字段。
实操建议:
- 用
DB::table('users')->where('status', 1)->get()绕过模型,确认是不是模型层的问题 - 查一下字段实际类型:
php artisan tinker里运行Schema::getColumnType('users', 'status') - 对时间字段慎用字符串比较,优先用
whereDate()、whereTime()或 Carbon 实例
软删除模型默认过滤掉 deleted_at 不为空的记录
如果你用的是 SoftDeletes trait,但没意识到当前记录已被软删,就会查不到。最简单的验证方式是加 withTrashed() 看能不能捞出来:User::withTrashed()->where('email', 'test@example.com')->first()。
另外注意:forceDelete() 才真删,delete() 只是打标记;如果业务里混用了硬删和软删,表里可能有真正被删掉的行,这时连 withTrashed() 都查不到。
关系查询返回空?重点看外键和本地/外键配置
比如 $user->posts 是空的,不一定是数据问题,很可能是 Post 模型里 belongsTo(User::class) 没指定外键名,而数据库里用的是 author_id,但 Eloquent 默认找 user_id。
快速排查点:
- 检查关系方法里有没有显式传外键参数,例如:
return $this->belongsTo(User::class, 'author_id') - 用
DB::table('posts')->where('author_id', $user->id)->get()直接查,确认数据存在且外键值正确 - 留意命名习惯:Laravel 默认用单数模型名 +
_id当外键,User→user_id,不是users_id或userId
最常被忽略的是时间范围条件写成了未来时间,或者用了 whereNotNull('updated_at') 却忘了刚插入的记录可能还没触发更新逻辑;调试时别只盯着模型代码,顺手 SELECT * FROM ... WHERE ... 复制 SQL 到数据库客户端跑一遍,比猜快得多。


















