OceanBase LOB 数据接口

2021-06-30 15:42 更新

OceanBase Connector/J 提供了用于写入和读取整个 LOB 内容的简化机制,称为数据接口。

数据接口使用标准的 JDBC 方法(如 getString 和 setBytes)读取和写入 LOB 数据。使用数据接口更易于编码且速度更快, 但与标准 java.sql.Blobjava.sql.Clob 和 java.sql.NClob 接口不同,它不提供随机访问功能,并且访问数据量不能超出 2147483648 个元素。

Input

OceanBase Connector/J 扩展了 PreparedStatement 的 setBytessetBinaryStreamsetStringsetCharacterStream 和 setAsciiStream 方法,以增强使用 BLOBCLOB 和 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 字节的数据使用流绑定。

  • setAsciiStreamsetBinaryStream 和 setCharacterStream 方法将长参数作为表单长度,使用长度大于 2147483648 的 LOB 绑定。未指定长度的表单始终使用 LOB 绑定。

  • setStringsetCharacterStream 和 setAsciiStream 方法对小于 32767 个字符的数据使用直接绑定。

  • setStringsetCharacterStream 和 setAsciiStream 方法对大于 32766 个字符的数据使用流绑定。

  • setCharacterStream 方法的新形式需要使用 long 参数的中作为长度,对大于 2147483647 的长度使用 LOB 绑定。未指定长度的表单始终使用 LOB 绑定。

对于 PL 语句,输入模式的使用注意事项如下:

  • setBytes 和 setBinary 流式方法对小于 32767 字节的数据使用直接绑定。

  • setBytes 和 setBinaryStream 方法对大于 32766 字节的数据使用 LOB 绑定。

  • setStringsetCharacterStream 和 setAsciiStream 方法对数据库字符集中小于 32767 字节的数据使用直接绑定。

    说明 

    BLOB 无法使用 setString 来设置。

  • setStringsetCharacterStream 和 setAsciiStream 方法对数据库字符集中大于 32766 字节的数据使用 LOB 绑定。

自动切换输入模式会影响某些程序。自动切换也可能导致附加的服务器端解析,以适应参数类型的更改。如果重复执行语句时,数据大小在阈值上下不断变化,则将导致性能影响。切换到流模式也会影响批处理。

Output

ResultSet 和 CallableStatement 的 getBytesgetBinaryStreamgetStringgetCharacterStream 和 getAsciiStream 方法已扩展为可与 BLOBCLOB 或 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)供应商提供的有关大量数据元素影响内存管理的相关信息,并考虑改用流接口。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号