添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

金仓数据库KingbaseES客户端编程接口指南-JDBC(6. JDBC 大对象数据处理)

数据猿 2022-08-03
135

6. JDBC 大对象数据处理

在 KingbaseES 中,大对象数据用于保存那些无法在通常 SQL 表里面保存的数据,例如声音、图象、大文本等。在 KingbaseES 兼容 oracle 版本中提供了用来存储大对象数据的数据类型 BLOB 和 CLOB,用来存储大数据量的二进制数据和字符数据。在兼容 PG 的版本中,大对象统一存储在一张系统表中,用户表中只存储大对象实际存储的地址,类型为oid。

KingbaseES JDBC 中提供了两个接口用于处理大对象数据:java.sql.Blob 和 java.sql.Clob。oracle 兼容模式下数据库提供了两种类型来存储数据,接口提供的两个类分别对应处理这两种数据类型,故两个类的接口均已实现。但在PG兼容模式下数据库对大对象统一存储,且驱动的 Clob 的类只实现了部分获取数据的接口,设置数据的接口均未实现,故 Clob 接口只能进行数据的接收,如果要更新大对象数据只能使用 Blob 的接口。Clob 接口在两种兼容情况下的具体实现情况可参照 JDBC Clob API

6.1. 大对象数据的读取

同检索其他数据类型一样,用同样的方法可以从一个结果集中检索 Blob 和 Clob 这两种数据类型的数据,该获得方法为:

Blob blob = rs.getBlob();
Clob clob = rs.getClob();

与其它数据类型不同,调用 getBlob() 和 getClob() 之后,需要使用 Blob 和 Clob 接口的方法访问数据。

oracle兼容模式下:

用下面脚本创建包含 Clob 字段的表:

CREATE TABLE clob_table(col1 Clob, col2 Clob, col3 Clob);

用下面脚本创建包含 Blob 字段的表:

CREATE TABLE blob_table(col1 Blob, col2 Blob, col3 Blob);

PG兼容模式下:

用下面脚本创建包含 Clob 字段的表:

CREATE TABLE clob_table(col1 oid, col2 oid, col3 oid);

用下面脚本创建包含 Blob 字段的表:

CREATE TABLE blob_table(col1 oid, col2 oid, col3 oid);

例 6-1. Clob 查询示例

这个例子展示了如何查询 Clob 字段

处理 Clob 的 java 程序段:

String sql_select = "select * from clob_table";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql_select);
int count = 1;
/* 1.以字符串的方式显示 */
while (resultSet.next())
    System.out.println("第" + count + "条记录");
    Clob clob1 = resultSet.getClob(1);
    Clob clob2 = resultSet.getClob(2);
    Clob clob3 = resultSet.getClob(3);
    System.out.println("clob1:" + clob1.getSubString(1, (int)
    clob1.length()));
    System.out.println("clob2:" + clob2.getSubString(1, (int)
    clob2.length()));
    System.out.println("clob3:" + clob3.getSubString(1, (int)
    clob3.length()));
    count++;
resultSet.close();
count = 1;
resultSet = statement.executeQuery(sql_select);
/*  2.取出clob对象,进行相关操作 */
while (resultSet.next())
    System.out.println("第" + count + "条记录");
    for (int i = 0; i < 3; i++)
        Clob clob = resultSet.getClob(i + 1);
        /*  使用getCharacterStream方法获得Clob列的数据。 */
        Reader reader = clob.getCharacterStream();
        StringWriter sWriter = new StringWriter();
        int j = -1;
        while ((j = reader.read()) != -1)
            sWriter.write(j);
        /*  显示Clob列的数据。 */
        String finalClob = new String(sWriter.getBuffer());
        System.out.println(finalClob);
    count++;
resultSet.close();

例 6-2. Blob 查询示例

这个例子展示了如何查询 Blob 字段

处理 Blob 的 java 程序段:

String sql_select = "select * from blob_table";
statement = connection.createStatement();
resultSet = statement.executeQuery(sql_select);
int count = 1;
/*  1.以字符串的方式显示 */
while (resultSet.next())
    System.out.println("第" + count + "条记录");
    Blob blob1 = resultSet.getBlob(1);
    Blob blob2 = resultSet.getBlob(1);
    Blob blob3 = resultSet.getBlob(1);
    System.out.println("blob1: " + new String(blob1.getBytes(1, (int)
    blob1.length())));
    System.out.println("blob2: " + new String(blob2.getBytes(1, (int)
    blob2.length())));
    System.out.println("blob3: " + new String(blob3.getBytes(1, (int)
    blob3.length())));
    count++;
resultSet.close();
count = 1;
resultSet = statement.executeQuery(sql_select);
/*  2.取出blob对象,进行相关操作 */
while (resultSet.next())
    System.out.println("第" + count + "条记录");
    for (int i = 0; i < 3; i++)
        Blob blob = resultSet.getBlob(i + 1);
        /*  使用getBinaryStream方法获得blob列的数据。 */
        InputStream input = blob.getBinaryStream();
        StringWriter sWriter = new StringWriter();
        int j = -1;
        while ((j = input.read()) != -1)
            sWriter.write(j);
        /*  显示blob列的数据。 */
        String finalblob = new String(sWriter.getBuffer());
        System.out.println(finalblob);
    count++;
resultSet.close();

6.2. 大对象数据的更新

在 PreparedStatement 类中,可以使用 setBlob() 和 setClob() 方法把 Blob 和 Clob 对象当成参数传递给 SQL 语句。例如:authorImage 和 authorBio 是通过其它 SQL 语句检索出来的 Blob 和 Clob 对象:

PreparedStatement pstmt = conn.prepareStatement(
    "insert into bio(image,text) values(?,?)");
pstmt.setBlob(1,authorImage);
pstmt.setClob(2,authorBio);
pstmt.executeUpdate();

完整的示例请参见下文。

此外,在oracle兼容模式下,通过 PrepareStatement 对象的 setBinaryStream、setBytes 和 setObject 可以设置语句中的 Blob 类型的参数;使用 setCharacterStream、setString、setAsciiStream 和 setObject 方法可以设置 Clob 类型的参数。

请看下面完整的示例。例 6-3、6-4、6-5只能在oracle兼容模式下执行,例 6-6 在 PG 和 oracle 兼容模式下均可执行。

用下面脚本创建包含 Clob 字段的表:

CREATE TABLE clob_table(col1 Clob, col2 Clob, col3 Clob);

用下面脚本创建包含 Blob 字段的表:

CREATE TABLE blob_table(col1 Blob, col2 Blob, col3 Blob);

例 6-3. Clob 插入示例

这个例子展示了如何向 Clob 列插入数据

处理 Clob 的 java 程序段:

/*
 *  插入 Clob 数据
String sql_insert = "insert into clob_table values(?,?,?)";
/*  从文件读取数据插入,以 setCharacterStream 方式插入 */
File file = new File("e:/test.xml");
Reader read1, read2, read3;
read1 = new FileReader(file);
read2 = new FileReader(file);
read3 = new FileReader(file);
preparedStatement = connection.prepareStatement(sql_insert);
preparedStatement.setCharacterStream(1, read1);
preparedStatement.setCharacterStream(2, read2);
preparedStatement.setCharacterStream(3, read3);
preparedStatement.execute();
/*  直接插入字符串 */
String str = "Welcome to Kingbase!";
preparedStatement = connection.prepareStatement(sql_insert);
preparedStatement.setString(1, str);
preparedStatement.setString(2, str);
preparedStatement.setString(3, str);
preparedStatement.execute();

例 6-4. Blob 插入示例

这个例子展示了如何向 Blob 列插入数据

处理 Blob 的 java 程序段:

/*
 *  插入 Blob 数据
String sql_insert = "insert into blob_table values(?,?,?)";
/*  从文件读取数据插入,以 setBinaryStream 方式插入 */
File file = new File("e:/test.xml");
InputStream input1, input2, input3;
input1 = new FileInputStream(file);
input2 = new FileInputStream(file);
input3 = new FileInputStream(file);
preparedStatement = connection.prepareStatement(sql_insert);
preparedStatement.setBinaryStream(1, input1);
preparedStatement.setBinaryStream(2, input2);
preparedStatement.setBinaryStream(3, input3);
preparedStatement.execute();
/*  直接插入字符串 */
String str = "Welcome to Kingbase!";
preparedStatement = connection.prepareStatement(sql_insert);
preparedStatement.setBytes(1, str.getBytes());
preparedStatement.setBytes(2, str.getBytes());
preparedStatement.setBytes(3, str.getBytes());
preparedStatement.execute();

例 6-5. Clob 更新示例

这个例子展示了如何使用 Clob 的 setCharacterStream、setAsciiStream 和 setString 方法更新 Clob 字段

处理 Clob 的 java 程序段:

/*
 * 使用 Clob 的 setAsciiStream、setCharacterStream 和 SetString 方法更新
 * Clob 列。
String query = "Select * from clob_table for update";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.next())
    Clob clob = resultSet.getClob(1);
     * 使用 setAsciiStream 方法更新 Clob 列,其中 clob.length() + 1 表示在
     * 原值后追加新的值,
     * 原值为 “Welcome to Kingbase!”,更新后的值为 “Welcome to Kingbase!
     * Test has sucessful!”。
    OutputStream os = clob.setAsciiStream(clob.length() + 1);
    String temp = "Test has sucessful!";
    byte[] tempByte = temp.getBytes();
    os.write(tempByte);
    os.close();
     * 使用 setCharacterStream 方法更新 Clob 列,其中 clob.length() + 1
     * 表示在原值后追加新的值,
     * 原值为 “Welcome to Kingbase!”,更新后的值为 “Welcome to Kingbase!
     * Welcome to Kingbase!”。
    clob = resultSet.getClob(2);
    Writer writer = clob.setCharacterStream(clob.length() + 1);
    temp = "Welcome to Kingbase!";
    writer.write(temp);
    writer.close();
     * 使用 setString 方法更新 Clob 列,其中 temp.length() 表示原值的更新
     * 位置,如果原值的长度
     * 大于或者等于 temp.length() 的值,则新值代替对应位置的原值;否则原值
     * 长度小于 temp.length() 的
     * 值,更新时会报错。原值为 “Welcome to Kingbase!”,更新后的值为
     * “Welcome to KingHello, Kingbase!”。
    clob = resultSet.getClob(3);
    temp = "Hello, Kingbase!";
    clob.setString(clob.length() + 1, temp);

例 6-6. Blob 更新示例

这个例子展示了如何使用 Blob 的 setBinaryStream 和 setBytes 方法更新 Blob 字段

处理 Blob 的 java 程序段:

 /*
  * 使用 Blob 的 setBinaryStream 和 setString 方法更新 blob 列。
String query = "Select * from blob_table for update";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.next())
    Blob blob = resultSet.getBlob(1);
     * 使用 setBinaryStream 方法更新 blob 列,其中 blob.length() + 1 表示
     * 在原值后追加新的值。
     * 原值为 “Welcome to Kingbase!”,更新后的值为 “Welcome to Kingbase!
     * Welcome to Kingbase!”。
    OutputStream output = blob.setBinaryStream(blob.length() + 1);
    String temp = "Welcome to Kingbase!";
    output.write(temp.getBytes());
    output.close();
     * 使用 setBytes 方法更新 blob 列,其中 blob.length() + 1 表示原值的
     * 更新位置,如果原值的长度大于或者等于 blob.length() + 1 的值,则新值
     * 代替对应位置的原值;否则原值长度小于 blob.length() + 1
     * 的值,更新时会报错。原值为 “Welcome to Kingbase!”,更新后的值为
     * “Welcome to Kingbase!Hello, Kingbase!”。
    blob = resultSet.getBlob(2);