OceanBase LOB 数据接口
OceanBase Connector/J 提供了用于写入和读取整个 LOB
内容的简化机制,称为数据接口。
数据接口使用标准的 JDBC 方法(如 getString
和 setBytes
)读取和写入 LOB
数据。使用数据接口更易于编码且速度更快, 但与标准 java.sql.Blob
、java.sql.Clob
和 java.sql.NClob
接口不同,它不提供随机访问功能,并且访问数据量不能超出
2147483648 个元素。
Input
OceanBase Connector/J 扩展了 PreparedStatement
的 setBytes
、setBinaryStream
、setString
、setCharacterStream
和 setAsciiStream
方法,以增强使用 BLOB
、CLOB
和 NCLOB
的能力。
对于服务器端内部驱动程序,当前对 SQL 语句(如 INSERT
语句)的操作限制为 4000 字节。此限制不适用于 PL 语句。INSERT
语句通过包裹在 PL 块中来解决这一限制,方法如下:
BEGIN
INSERT id, name INTO clob_emp VALUES(?,?);
END
对于大型数据共有三种输入模式,如下所示:
-
直接绑定
此绑定方式的大小受到限制,但效率最高。它将所有输入列的数据内联在的数据块中,再发送到服务器。所有数据(包括批处理的多次执行)都在单个网络操作中发送。
-
流绑定
此绑定将数据放在末尾。它将批量大小限制为一个,因而可能需要多次往返才能完成。
-
LOB
绑定此绑定创建一个临时
LOB
,将数据复制到LOB
,并绑定LOB
定位器。临时LOB
在执行后自动释放。创建临时LOB
然后写入LOB
的操作需要多次往返。定位器的输入可以是成批的。
对于 SQL 语句,输入模式的使用注意事项如下:
-
setBytes
和setBinaryStream
方法对小于 4001 字节的数据使用直接绑定。 -
setBytes
和setBinaryStream
方法对大于 4000 字节的数据使用流绑定。 -
setAsciiStream
、setBinaryStream
和setCharacterStream
方法将长参数作为表单长度,使用长度大于 2147483648 的LOB
绑定。未指定长度的表单始终使用LOB
绑定。 -
setString
、setCharacterStream
和setAsciiStream
方法对小于 32767 个字符的数据使用直接绑定。 -
setString
、setCharacterStream
和setAsciiStream
方法对大于 32766 个字符的数据使用流绑定。 -
setCharacterStream
方法的新形式需要使用long
参数的中作为长度,对大于 2147483647 的长度使用LOB
绑定。未指定长度的表单始终使用LOB
绑定。
对于 PL 语句,输入模式的使用注意事项如下:
-
setBytes
和setBinary
流式方法对小于 32767 字节的数据使用直接绑定。 -
setBytes
和setBinaryStream
方法对大于 32766 字节的数据使用LOB
绑定。 -
setString
、setCharacterStream
和setAsciiStream
方法对数据库字符集中小于 32767 字节的数据使用直接绑定。说明BLOB
无法使用setString
来设置。 -
setString
、setCharacterStream
和setAsciiStream
方法对数据库字符集中大于 32766 字节的数据使用LOB
绑定。
自动切换输入模式会影响某些程序。自动切换也可能导致附加的服务器端解析,以适应参数类型的更改。如果重复执行语句时,数据大小在阈值上下不断变化,则将导致性能影响。切换到流模式也会影响批处理。
Output
ResultSet
和 CallableStatement
的 getBytes
、getBinaryStream
、getString
、getCharacterStream
和 getAsciiStream
方法已扩展为可与 BLOB
、CLOB
或 OUT
参数一起使用。
这些方法适用于长度小于 2147483648 的任何 LOB
。
说明
getString
和getNString
方法不能用于检索BLOB
列值。
数据接口通过访问驱动程序中的 LOB
定位器进行操作,并且对应用程序编程是透明的。可以根据需要使用 LOB
预取来减少或消除的其他数据库往返行程。
可以使用与 LONG RAW
和 LONG
数据相同的流式传输机制来读取和写入 BLOB
或 CLOB
数据。可以在列上使用 defineColumnType(nn,Types.LONGVARBINARY)
或 defineColumnType(nn,Types.LONGVARCH
方法来读取数据,产生直接流,就好像是读取 LONG RAW
或 LONG
列的数据一样。
CallableSatement 和 IN OUT 参数
PL 要求用作 IN OUT
参数输入和输出的 Java 类型必须相同。
对于存储过程的 IN OUT CLOB
参数,希望使用 setString
方法设置该参数的值。对于任何 IN
和 OUT
参数,必须对相同的类型进行绑定。如果无法确定数据大小,则自动切换输入模式会引发错误。例如,如果知道输入数据和输出数据都不会大于 32766 字节,则可以对输入参数使用 setString
方法,并将 OUT
参数注册为 Types.VARCHAR
,对输出参数使用 getString
方法。
更好的解决方案是将存储过程更改为具有单独的 IN
和 OUT
参数。 如下例所示:
CREATE PROCEDURE clob_obproc( cc IN OUT CLOB );
更改为如下示例:
CREATE PROCEDURE clob_obproc( cc_in IN CLOB, cc_out OUT CLOB );
另一个解决方法是使用容器块进行调用。clob_plproc
存储过程可以用 Java 字符串包装,以用于 prepareCall
语句,如下所示:
"DECLARE cc_temp; BEGIN cc_temp := ?; clob_plproc( cc_temp); ? := cc_temp; END;"
无论哪种情况,都可以在第一个参数上使用 setString
方法,在第二个参数上使用 registerOutParameter
方法和 Types.CLOB
。
大小限制
如果创建非常大的 byte
数组或 String 可能会对 Java 内存管理系统的性能产生影响。阅读 Java 虚拟机(JVM)供应商提供的有关大量数据元素影响内存管理的相关信息,并考虑改用流接口。