跳转到主内容
极星编程网:以代码为星,赴技术山海!

Oracle 19c中LONG类型如何转换为Java String_使用ResultSet.getCharacterStream

不能用 getString() 读取 Oracle 的 LONG 列,因自12c起JDBC驱动默认禁用其直接映射,会报“Invalid column type”或截断;必须用 getCharacterStream() 流式读取以完整获取最大2GB内容。 直接用
resultset.getstring()
读取 oracle 的
long
列,在 19c 及较新 jdbc 驱动(ojdbc8+)下大概率会抛
java.sql.sqlexception: invalid column type
或静默截断——这不是 bug,是 oracle 明确弃用
long
后的兼容性限制。必须改用流式读取。 为什么不能用 getString() 读取 LONG Oracle 自 8i 起就标记
LONG
为“过时类型”,12c 后 JDBC 驱动默认禁用其直接映射。驱动会把
LONG
列识别为
OTHER
或
LONGVARBINARY
类型,
getString()
拒绝处理非字符类型列。即使侥幸返回字符串,长度也常被截断到 4000 字节以内。 getCharacterStream() 是最稳妥的替代方案 它绕过类型映射,让 JDBC 驱动以字符流方式拉取数据,底层实际调用 Oracle 的 LOB 流接口,能完整读取最大 2GB 的
LONG
内容。
ResultSet.getCharacterStream("col_name")
返回
java.io.Reader
,需手动读取至
String
必须在同一次
ResultSet
迭代中完成读取,流关闭后无法重读 不支持随机访问或
mark()/reset()
,只能顺序读到底 若列值为
NULL
,返回
null
,需判空 实际读取代码要防阻塞和内存溢出 别用
readLine()
循环——遇到换行符就停,会丢内容。用固定缓冲区 +
StringBuilder
才可靠:
Reader reader = rs.getCharacterStream("long_col"); if (reader != null) { StringBuilder sb = new StringBuilder(); char[] buf = new char[4096]; int len; while ((len = reader.read(buf)) != -1) { sb.append(buf, 0, len); } String result = sb.toString(); }
缓冲区大小选
4096
是平衡 IO 次数与堆内存占用的常见值 避免用
StringBuffer
(同步开销无必要),单线程场景
StringBuilder
足够 别漏掉
reader.close()
—— 虽然
ResultSet.close()
通常会级联关闭,但显式关闭更安全 MyBatis 中怎么配 MyBatis 默认不支持
LONG
,需显式指定
jdbcType
并配合自定义
TypeHandler
: Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; XML 映射里写:
但
LONGVARCHAR
在 ojdbc8 下仍可能失败,更稳的是用
jdbcType="OTHER"
+ 自定义 handler handler 中复用上面的
getCharacterStream()
逻辑,而不是依赖
rs.getString()
注意:MyBatis 的
@Select
注解方法无法指定
jdbcType
,必须用 XML 或
@Results
真正麻烦的不是读取动作本身,而是整个链路——从 Oracle 服务端返回流、JDBC 驱动解析、Java 层缓冲区管理,任一环节超时或中断都会导致数据不全。生产环境务必加超时控制和日志记录原始字节数,否则出问题时连是不是读全了都难验证。

相关文章