必须用流式读取+显式资源管理处理CLOB,禁用getString():因其会静默截断、误判NULL、泄漏LOB句柄;推荐getClob().getCharacterStream()+BufferedReader分段读取,并调用free()。

Java JDBC 处理超长文本(如 Oracle/MySQL 的 CLOB 字段)必须避免用 getString() 直接加载——它容易截断、返回 null 或引发 OOM。核心原则是:用流式读取 + 显式资源管理。
为什么不能用 getString() 读 CLOB
Oracle JDBC 驱动对 getString() 有隐式长度限制(例如 12c 默认 4000 字节),超长内容会被静默截断;字段为 SQL NULL 时还可能返回空字符串而非 null,导致业务误判;在 auto-commit=false 场景下,未释放 LOB 句柄还会污染连接池。所以必须绕过 getString,走标准 CLOB 接口。
推荐分段读取方式:getCharacterStream() + BufferedReader
适用于任意长度的文本,尤其 >2GB 或内存受限场景:
- 调用
rs.getClob("content")获取 Clob 对象,先判空:if (clob != null) - 用
clob.getCharacterStream()得到Reader,不要转成 String - 包装为
BufferedReader,按需读取(如每次readLine()或read(char[])) - 读完后显式调用
clob.free()(JDBC 4.0+ 要求,防止句柄泄漏)
小文件可选方案:getSubString() 全量读取
仅当确认内容远小于 JVM 堆内存(比如
立即学习“Java免费学习笔记(深入)”;
- 先检查
clob != null,再调用clob.length() - 若长度 ≤
Integer.MAX_VALUE(约 2GB),可用clob.getSubString(1, (int) clob.length()) - 注意:超过 2GB 会抛
SQLException,不可强转 int
写入超长文本也要分段绑定
用 setString() 写入长文本会触发 ORA-01461 错误(驱动误当 VARCHAR2 处理)。正确做法:
- 用
conn.createClob()创建临时 CLOB 对象 - 调用
clob.setString(1, largeText)写入内容(支持自动分块) - 再通过
ps.setClob(1, clob)绑定到 PreparedStatement - 批量操作务必关闭自动提交:
conn.setAutoCommit(false)


















