You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Laravel Eloquent查询含真值的列及相关技术疑问

问题背景

我有一个Post模型,对应的is_verified列数据类型为smallint。原本使用以下Eloquent代码查询所有已验证的记录:

Post::where('is_verified', true)->get();

这段代码生成的SQL语句如下:

select * from `posts` where `posts`.`is_verified` = true

当is_verified的值为0或1时,该查询能正常获取已验证的Post记录;但当我手动将部分记录的is_verified值改为2这类非1的“真值”后,上述Eloquent查询无法获取到这些记录。直接执行该SQL语句也存在同样问题,而将SQL中的=改为is后,查询可正常获取所有含真值的记录:

select * from `posts` where `posts`.`is_verified` is true

我的疑问:

  1. 上述行为是否符合预期?
  2. 如何用Eloquent执行上述使用is true的SQL查询?我想到的方式是where('is_verified', '!=', 0),但在复杂长查询中可读性较差。
  3. is_verified列的smallint类型是否会影响该行为?因为相关讨论提到布尔列通常为tinyint而非smallint。

回答

1. 该行为完全符合预期

在SQL语法中,=属于等值比较运算符,当你写= true时,数据库会将true转换为对应的数值(多数数据库中是1),所以is_verified = true本质上等价于is_verified = 1,自然匹配不到值为2的记录。而is true是布尔逻辑判断,数据库会将所有非0的数值判定为真,因此能匹配所有非0的is_verified值。

2. 用Eloquent实现is true查询的几种方案

  • 直接使用whereRaw写入原生SQL条件:
    Post::whereRaw('is_verified is true')->get();
    
    这种方式最直接,完全还原你需要的SQL逻辑,可读性较强。
  • 自定义查询作用域(推荐复杂查询场景):
    在Post模型中定义一个查询作用域:
    public function scopeVerified($query)
    {
        return $query->whereRaw('is_verified is true');
    }
    
    后续查询时直接调用该作用域即可,复杂查询中会让代码更简洁易读:
    Post::verified()->get();
    
  • 结合DB::raw使用where方法:
    借助DB::raw构造表达式,也能实现需求:
    use Illuminate\Support\Facades\DB;
    
    Post::where(DB::raw('is_verified'), 'is', true)->get();
    

3. smallint类型不影响核心行为

不管是tinyint还是smallint,只要是整数类型,数据库对= true和is true的处理逻辑是一致的:= true会转为等值匹配1,is true会判断非0值为真。两者的区别仅在于存储空间——tinyint占用空间更小,更适合存储布尔值(毕竟布尔只需要0/1两种状态),但这和你遇到的查询行为没有直接关联。


内容的提问来源于stack exchange,提问作者rifqy abdl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:20:30