🔍 问题现象
数据库中 lesson_plan_record.content 字段存储的是合法 JSON(类型为 JSON)。
但在 Java 端通过 MyBatis-Plus 查询时,content 字段始终为 null。
MyBatis 日志显示该列值为 <<BLOB>>,说明 JDBC 将其视为二进制数据。
🧩 根本原因
- MySQL 的 JSON 类型在 JDBC 中以 BLOB 形式返回
即使字段定义为 JSON,底层仍按 BLOB 传输。
调用 ResultSet.getString("content") 会返回 null,无法直接获取字符串。
- MyBatis-Plus 默认不调用自定义 TypeHandler
虽然你写了 @TableField(typeHandler = LessonPlanContentTypeHandler.class),
但 未启用 autoResultMap = true,导致 MyBatis-Plus:
不生成 <resultMap>
忽略 typeHandler
直接跳过复杂类型字段 → content = null
💡 换句话说:你的 TypeHandler 根本没被执行!
✅ 正确解决方案
步骤 1:在实体类上启用自动 ResultMap
Java
编辑
1@TableName(value = "lesson_plan_record", autoResultMap = true) // ⭐ 关键!
2public class LessonPlanRecord {
3 // ...
4}
步骤 2:确保 TypeHandler 能处理 BLOB 类型
使用 rs.getObject() 读取原始数据,并兼容 byte[] / Blob / String:
Java
编辑
1@Override
2public AiGeneratedLessonPlan getNullableResult(ResultSet rs, String columnName) throws SQLException {
3 Object obj = rs.getObject(columnName); // ✅ 正确方式
4 return parseObject(obj);
5}
步骤 3:重启应用,验证结果
📌 关键知识点
概念 说明
autoResultMap = true 启用后,MyBatis-Plus 才会为复杂字段生成 <resultMap> 并应用 typeHandler
MySQL JSON 类型 在 JDBC 中默认作为 BLOB 返回,不能直接用 getString()
getObject() vs getString() 处理 JSON/BLOB 字段必须用 getObject()
✅ 最终效果
成功从数据库读取 JSON 字段
自动反序列化为 AiGeneratedLessonPlan 对象
前端收到完整的教案内容,不再为 null
❌ 常见误区
"我写了 typeHandler 就应该生效" → 错!必须配合 autoResultMap = true
"字段是 JSON 类型,肯定能当字符串读" → 错!JDBC 返回的是 BLOB
"只改一个 getNullableResult 方法就行" → 错!MyBatis-Plus 调用的是按列名的版本