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

Go+MySQL中如何在预处理语句WHERE子句使用JSON_EXTRACTOR?

问题描述

我有如下表结构:

CREATE TABLE IF NOT EXISTS test_table (
    id CHAR(36) NOT NULL,
    json JSON,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

我希望基于json字段的内容过滤SELECT查询。使用Go语言结合sqlx(扩展golang/sql)编写了如下代码:

query := "SELECT * FROM test_table WHERE json->'$.alive' = ?"
rows, err := db.QueryxContext(ctx, query, true)
if err != nil {
    fmt.Println(err)
}
defer rows.Close()
for rows.Next() {
    var id int
    var json string
    rows.Scan(&id, &json)
}

该代码返回空结果集,但在DataGrip中执行相同逻辑的查询能得到预期结果。我已在最简复现环境中测试,问题仍存在且无报错。

目前我可以通过拼接SQL语句(如query := "SELECT * FROM test_table WHERE json->'$.alive' = true")绕过,但希望避免这种方式。我尝试过传入字符串"true"、数字1(因MySQL底层用TINYINT存储布尔值)以及完整写法JSON_EXTRACT,均无效,恳请提供帮助。

环境信息:

  • go1.19.11 linux/amd64
  • mysql8.0.33 for Linux on x86_64
  • github.com/go-sql-driver/mysql v1.6.0
  • github.com/jmoiron/sqlx v1.3.5
解决办法

核心问题是MySQL对JSON布尔值的类型匹配规则:参数化查询时,Go驱动会把布尔值true转为MySQL的TINYINT(1)类型,但json->'$.alive'返回的是JSON原生布尔类型,两者类型不匹配导致查询无结果。以下是几种可行的解决方式:

1. 强制将参数转为JSON类型

通过CAST(? AS JSON)把传入的字符串参数转为JSON布尔值,和JSON字段提取出的值做类型匹配:

query := "SELECT * FROM test_table WHERE json->'$.alive' = CAST(? AS JSON)"
rows, err := db.QueryxContext(ctx, query, "true")

或者使用MySQL的JSON_EQUAL函数,它会忽略类型差异直接比较JSON值:

query := "SELECT * FROM test_table WHERE JSON_EQUAL(json->'$.alive', ?)"
rows, err := db.QueryxContext(ctx, query, "true")

2. 使用->>操作符提取字符串值

->>会将JSON值直接转为字符串类型,此时传入字符串"true"即可匹配:

query := "SELECT * FROM test_table WHERE json->>'$.alive' = ?"
rows, err := db.QueryxContext(ctx, query, "true")

3. 修复Scan时的类型错误

你的代码中存在一个隐藏问题:表结构里id是CHAR(36)(UUID类型),但你用int类型接收,这会导致Scan失败(只是未处理错误所以没发现)。应将id改为string类型:

for rows.Next() {
    var id string
    var jsonStr string
    if err := rows.Scan(&id, &jsonStr); err != nil {
        fmt.Println(err)
        continue
    }
    // 处理数据逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:25:15