核心是让查询条件类型与数据库字段类型严格一致:查表结构确认字段真实类型,sql中字符串加引号、数字不加引号,java用对应set方法或解析后传值,mybatis指定jdbctype,json字段查询须镜像索引表达式。

核心就一条:让查询条件的类型和数据库字段类型完全一致,不靠 MySQL 自己“猜”。
查清楚字段真实类型
别只看业务代码或 ORM 映射,直接查表结构:
- 执行 DESCRIBE table_name 或 SHOW CREATE TABLE table_name
- 确认关键查询字段是 INT、VARCHAR、DATETIME 还是 JSON
- 特别注意 JSON 字段里提取的值默认是字符串,哪怕原始数据是数字
写 SQL 时严格对齐类型
字符串字段就用引号,数字字段就别加引号:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
user_id INT → 写 WHERE user_id = 123,不是
'123' -
order_no VARCHAR → 写 WHERE order_no = 'ORD-001',不是
ORD-001(没引号会当标识符) -
create_time DATETIME → 用 STR_TO_DATE('20260729', '%Y%m%d') 或标准格式
'2026-07-29 00:00:00',避免'20260729'这种模糊字符串
Java 代码里别被 setString 欺骗
JDBC 的 setString(1, "123") 对 INT 字段,MySQL 仍收到字符串——隐式转换照旧发生:
- 真正起作用的是传过去的值类型,不是方法名
- 对数字字段,显式用 setInt(1, 123)、setLong(1, 123L)
- 如果参数来自前端字符串,先解析再传:
Integer.parseInt(userIdStr),并处理空值和异常 - MyBatis 中,
#{userId}加上 jdbcType=INTEGER,或确保传入对象的字段类型是Integer而非String
JSON 和函数索引要“镜像匹配”
JSON 字段里存了 {"score": 85},想走索引就得完全复刻建索引时的表达式:
- 建索引用了
CAST(JSON_EXTRACT(data, '$.score') AS UNSIGNED) - 查询就必须写成 CAST(JSON_EXTRACT(data, '$.score') AS UNSIGNED) = 85,不能写
= '85'或= 85.0 - PostgreSQL 更严格:
data->>'score'返回 text,数值比较必须加::int,漏掉就全表扫描
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










