MySQL无原生BOOLEAN类型,TINYINT(1)本质是1字节整数,括号中“1”仅为显示宽度;JDBC驱动默认启用tinyInt1isBit=true将0/1转为true/false,MyBatis据此映射为Boolean,导致类型异常。

MySQL 本身没有原生 BOOLEAN 类型,TINYINT(1) 只是社区约定俗成的“布尔替代方案”,它本质就是个 1 字节整数——查出来是 0 或 1,才是它最原始、最符合存储本质的表现。
MySQL 服务层:TINYINT(1) 就是 TINYINT,不是布尔
MySQL 不会把 TINYINT(1) 当作特殊类型处理。括号里的 1 是显示宽度(display width),仅影响 zerofill 场景下的输出对齐,和数据类型语义完全无关。实际存储范围仍是 -128~127(有符号)或 0~255(无符号)。你在 MySQL 客户端执行:
SELECT is_active FROM user_status;
看到的 0 和 1,就是 JDBC 驱动还没介入前、MySQL 原生返回的数值结果。
JDBC 驱动层:tinyInt1isBit=true 是“变布尔”的开关
真正让 0/1 变成 true/false 的,是 MySQL Connector/J 驱动的行为,默认开启 tinyInt1isBit=true。这个参数一开,驱动就会把元数据中标注为 TINYINT(1) 的列,主动映射为 Java 的 Boolean。
常见影响包括:
-
ResultSet.getObject("is_active")返回Boolean,不是Integer - MyBatis 的
resultType="Map"里该字段值变成true/false - 实体类中若声明为
Integer,但数据库字段是TINYINT(1),可能抛ClassCastException
MyBatis 映射层:跟着 JDBC 元数据走,不额外纠错
MyBatis 不会主动“纠正” JDBC 驱动的类型判断。它读取 ResultSetMetaData,发现某列被 JDBC 标记为 BIT(因为 tinyInt1isBit=true),就默认使用 BooleanTypeHandler。所以你看到的现象其实是三层叠加的结果:
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
MySQL 存的是整数 → JDBC 声称它是 BIT → MyBatis 相信了并转成布尔
如果你用 IFNULL(is_active, 0) 包裹字段,JDBC 就无法从元数据识别原始类型,自然不会触发 tinyInt1isBit 逻辑,结果就保持为 Integer。
怎么让查询稳定返回 0/1?关键在连接参数和字段定义
想彻底避免布尔化,优先从源头控制:
- 在 JDBC URL 中显式关闭:添加
&tinyInt1isBit=false,例如jdbc:mysql://localhost:3306/db?tinyInt1isBit=false - 建表时避开
TINYINT(1),改用TINYINT(4)或TINYINT(不带括号),驱动就不会触发特殊逻辑 - 如果必须用
TINYINT(1),且不能改驱动参数,就在 SQL 层 cast:用CAST(is_active AS SIGNED)或is_active + 0
最易被忽略的一点:Spring Boot 的 spring.datasource.url 配置里,& 符号必须写成 &(XML/HTML 实体),否则参数根本不会生效——很多人调了半天发现没用,卡在这儿。










