当前位置: 首页 > news >正文

达梦数据库踩坑:BLOB 数据类型 存中文文本读取变成十六进制乱码,CLOB 才是字符串大文本正确选择

一、问题现象

项目使用 SpringBoot + MyBatis-Plus + 达梦 DM8 开发,AI 分析结果表中存在两类大文本字段:

  1. CONCLUSIONSUMMARY:字段类型CLOB,前端 / 数据库客户端查询中文正常展示;
  2. SUGGESTIONBASIS:字段类型BLOB,查询出来不是可读中文,而是一串E59BA0E694BF...十六进制字符串。

数据库客户端、接口返回、后台日志全部都是十六进制 HEX 编码,肉眼完全无法识别中文内容,接口业务展示直接乱码失效。

中文数据变为HEX编码

二、根本原因拆解

1. BLOB 与 CLOB 本质区别(达梦数据库)

类型存储内容适用场景编码处理
CLOB字符大对象纯文本、中文、JSON、长文案数据库自动绑定字符集(UTF-8),读写自动编解码,JDBC 直接映射 JavaString
BLOB二进制字节大对象文件、图片、二进制流、字节数组只存原始字节,不绑定字符集,JDBC 读取返回原始 byte 数组

2. MyBatis-Plus + 达梦 JDBC 联动产生的 HEX 乱码

我们业务中字段存储的是 JavaString类型中文文本,但表定义错用BLOB

  1. 写入流程:Java String → JDBC 驱动将字符串转为 UTF-8 字节数组 → 存入 BLOB 二进制字段;
  2. 读取流程:查询 BLOB 字段 → JDBC 返回原始 byte [] → MyBatis-Plus 自动将字节数组转为十六进制 HEX 字符串展示;
  3. 最终表现:数据库里存的是中文 UTF-8 字节,查出来变成一串十六进制编码,肉眼看不到正常中文。

3. 为什么 CLOB 字段无问题

CLOB是字符型大对象,达梦 JDBC 驱动识别为文本类型,会自动根据库字符集完成字节 <-> 字符串转换,MyBatis 直接映射为 Java String,读写全程中文正常,不会出现十六进制乱码。

三、两种修复方案

方案一:数据库层修复(推荐,永久解决)

核心逻辑:达梦不支持BLOB直接ALTER MODIFY改为CLOB,必须走「新增临时 CLOB 字段 → 迁移数据 → 删除旧 BLOB 字段 → 重命名」流程。 以AUDIT_SUGGESTION字段举例:

-- 1. 新增临时CLOB字段 ALTER TABLE TEST.ANALYSIS_RESULT ADD TMP_AUDIT_SUGGEST CLOB; -- 2. 将BLOB二进制数据转为字符串写入CLOB(达梦内置函数UTL_RAW.CAST_TO_VARCHAR2) UPDATE XF_TEST.ANALYSIS_RESULT SET TMP_AUDIT_SUGGEST = UTL_RAW.CAST_TO_VARCHAR2(AUDIT_SUGGESTION); COMMIT; -- 3. 删除原有BLOB字段 ALTER TABLE TEST.ANALYSIS_RESULT DROP COLUMN SUGGESTION; -- 4. 临时字段重命名为原业务字段名 ALTER TABLE TEST.ANALYSIS_RESULT RENAME COLUMN TMP_AUDIT_SUGGEST TO AUDIT_SUGGESTION;

CLASSIFY_BASIS字段执行完全相同流程即可。

方案二:代码层临时兼容(不推荐,治标不治本)

如果暂时无法改表结构,在实体类 / 转换工具手动将 HEX 字节数组转回 UTF-8 字符串:

/** * BLOB十六进制字符串转中文文本 */ public static String hexBlobToText(String hexStr) { if (hexStr == null || hexStr.isEmpty()) { return ""; } byte[] bytes = new byte[hexStr.length() / 2]; for (int i = 0; i < bytes.length; i++) { int high = Character.digit(hexStr.charAt(2 * i), 16); int low = Character.digit(hexStr.charAt(2 * i + 1), 16); bytes[i] = (byte) (high << 4 | low); } return new String(bytes, StandardCharsets.UTF_8); }

缺陷:所有查询接口都要额外转换,增加大量冗余代码,后续新增字段极易重复踩坑。

四、开发规范避坑指南

  1. 文本类大内容统一使用 CLOB长文本、AI 返回文案、JSON、评论、政策说明、操作日志文本等,一律定义CLOB
  2. BLOB 仅用于二进制文件图片、PDF、压缩包、媒体文件等二进制流才使用BLOB,禁止存放字符串;
  3. 建表 SQL 统一校验字段类型 建表脚本提交前核对大文本字段,杜绝把业务字符串定义为 BLOB;
  4. 达梦类型转换限制提前知晓
    • VARCHAR/CHAR ↔ CLOB、BLOB ↔ CLOB 无法直接MODIFY修改,必须新增迁移;
    • BLOB 有数据时,不支持直接转为任何字符类型。

五、总结

本次乱码问题核心不是编码、驱动、MyBatis 配置问题,而是数据库字段类型选型错误:把字符串文本存进了二进制 BLOB 字段。 达梦数据库区分字符大对象 CLOB 与二进制大对象 BLOB,二者底层存储逻辑、JDBC 映射规则完全不同,混用会直接导致 HEX 十六进制乱码。 开发时严格区分业务数据类型,文本统一 CLOB、文件二进制统一 BLOB,从根源规避此类问题。

http://www.jsqmd.com/news/1196093/

相关文章:

  • [Uniapp]用户登录界面“记住密码”功能的安全存储与自动填充进阶实践
  • CMake 041:生成器表达式|骈文式拆解双路调试法门,逻辑运算符全解工程落地实战
  • 2026年 新疆/库尔勒新房现房置业分析:住宅/洋房观景毛坯房标杆项目解读 - 品牌发掘
  • 内网IM必须成为企业协同的安全底座
  • 参赛实测|以企业项目落地为例!聊聊AI赋能Java开发的真实体验
  • Tokio 中同步原语的实现解析:Mutex、RwLock 与 Notify 的底层 futex 机制
  • Cpp2IL故障排除实战:10个方法解决Unity逆向常见问题
  • MacBook Go版本升级:从版本检测到多版本管理的完整指南
  • 2026石家庄楼顶漏水、卫生间漏水、外墙、地下室渗漏怎么选?3家正规服务商(7月) - 防水企业百科
  • 遗传算法求解N皇后问题的Python实战与调试手记
  • 计算机毕业设计之基于SpringBoot的助老服务平台的设计
  • CHI协议保序之Order域实战解析:从Request到OWO
  • Agent 插件市场架构:动态加载工具与安全沙箱隔离
  • 异常订单兜底方案(延时队列之外全套兜底手段)
  • DS90UB935-Q1串行器时钟与I2C配置实战指南
  • 2026青岛地下室返潮、卫生间漏水、外墙、楼顶、阳台+阳光房渗漏不用愁!3家正规企业(7月) - 防水企业百科
  • 体育领域情感分析实战:基于预训练模型的球迷情绪追踪
  • 2026年最新北京市轨道交通图和 北京轨道交通规划图 附图
  • 2026香港高才通计划申请指南:世贸企业咨询助您高效获批香港身份 - 德益云企业服务
  • 基于STM32单片机车载CAN总线通信系统设计温度霍尔测速PWM设计DIY-T159
  • 教育警示短视频:从“催命符”比喻看家庭教育焦虑与平衡
  • 杭州GEO公司哪家好?2026企业选型避坑指南与推荐榜单 - 资讯纵览
  • 02 从CD4066到精密模拟开关:二选一电路设计的性能跃迁指南
  • 深入解析TI TPS65987D:USB PD 3.0、FRS、死电池供电与BC1.2实战设计
  • 《深入理解计算机系统》虚拟存储器
  • Prompt 效果漂移检测:模型偷偷更新了,Prompt 还在用旧的
  • TI CC2652RB无线MCU:BAW无晶体技术与多协议物联网开发实战
  • 2026达州卫生间漏水、外墙、楼顶、地下室、阳台渗漏怎么选?3家靠谱服务商(7月) - 防水企业百科
  • QOJ7937 题解
  • 自动驾驶横向控制算法——从几何模型到工程实践:Pure Pursuit的优化与挑战