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


    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);
        temp = "Hello, Kingbase!";
        blob.setBytes(blob.length() + 1, temp.getBytes());
    }
    

    6.3. JDBC Blob API

    1. public long length()

      功能:

      返回此 Blob 对象指定的 BLOB 值中的字节数。

      返回值:

      BLOB 的字节长度。

    2. public byte[] getBytes(long pos,int length)

      功能:

      以 byte 数组的形式获取此 Blob 对象表示的全部或部分 BLOB 值。此 byte 数组包含从位置 pos 开始的 length 个连续字节。

      参数:

      pos - 要提取的 BLOB 值中第一个字节的顺序位置;第一个字节位于位置 1 处。

      length - 要复制的连续字节的数量;length 的值必须大于等于 0。

      返回值:

      一个字节数组,它包含此 Blob 对象指定的 BLOB 值中的 length 个连续字节(从位置 pos 处的字节开始。

    3. public InputStream getBinaryStream()

      功能:

      以流的形式获取此 Blob 实例指定的 BLOB 值。

      返回值:

      包含 BLOB 数据的流。

    4. public long position(byte[] pattern,long start)

      功能:

      获取此 Blob 对象表示的 BLOB 值中指定 byte 数组 pattern 开始处的字节位置。对 pattern 的搜索从位置 start 开始。

      参数:

      pattern - 要搜索的字节数组。

      start - 开始搜索的位置;第一个位置是 1。

      返回值:

      pattern 出现的位置,否则返回 -1。

    5. public long position(Blob pattern,long start)

      功能:

      获取此 Blob 对象指定的 BLOB 值中 pattern 开始处的字节位置。从位置 start 开始搜索。

      参数:

      pattern - 指定要搜索的 BLOB 值的 Blob 对象。

      start - BLOB 值中开始进行搜索的位置;第一个位置是 1。

      返回值:

      pattern 开始处的位置,否则返回 -1。

    6. public int setBytes(long pos,byte[] bytes)

      功能:

      从位置 pos 处开始,将给定 byte 数组写入此 Blob 对象表示的 BLOB 值,并返回写入的字节数。该 byte 数组将从位置 pos 开始重写 Blob 对象中的现有字节。如果在写 byte 数组时到达 Blob 值的末尾,则将增加 Blob 值的长度,以容纳额外的字节。

      参数:

      pos - BLOB 对象开始进行写入操作的位置;第一个位置是 1。

      bytes - 要写入此 Blob 对象表示的 BLOB 值中的 byte 数组。

      返回值:

      写入的字节数。

    7. public int setBytes(long pos,byte[] bytes,int offset,int len)

      功能:

      将所有或部分给定的 byte 数组写入此 Blob 对象表示的 BLOB 值中,并返回写入的字节数。写入操作从 BLOB 值中的位置 pos 处开始;写入给定 byte 数组中的 len 个字节。该 byte 数组将从位置 pos 开始重写 Blob 对象中的现有字节。如果在写 byte 数组时到达 Blob 值的末尾,则将增加 Blob 值的长度,以容纳额外的字节。

      参数:

      pos - BLOB 对象开始进行写入操作的位置;第一个位置是 1。

      bytes - 要写入此 BLOB 对象中的 byte 数组。

      offset - 数组 bytes 中的偏移量,从此处开始读取要设置的字节。

      len - 要从 byte 数组 bytes 中写入 BLOB 值的字节数。

      返回值:

      写入的字节数。

    8. public OutputStream setBinaryStream(long pos)

      功能:

      获取用于写入此 Blob 对象表示的 BLOB 值的流。该流从位置 pos 处开始。写入流中的字节将从位置 pos 开始重写 Blob 对象中的现有字节。如果在写入流时到达 Blob 值的末尾,则将增加 Blob 值的长度,以容纳额外的字节。

      参数:

      pos - BLOB 值中开始进行写入操作的位置;第一个位置是 1 。

      返回值:

      可以将数据写入其中的 java.io.OutputStream 对象。

    9. public void truncate(long len)

      功能:

      截取此 Blob 对象表示的 BLOB 值,使其长度为 len 个字节。

      参数:

      len - 此 Blob 对象表示的 BLOB 值将被截取的字节长度。

    10. public void free()

      功能:

      此方法释放 Blob 对象以及它所占用的资源。调用 free 方法后,该对象将无效。

    11. public InputStream getBinaryStream(long pos,long length)

      功能:

      返回包含部分 Blob 值的 InputStream 对象,该值从 pos 指定的字节开始,长度为 length 个字节。

      参数:

      pos - 将获取的部分值第一个字节的偏移量。Blob 中的第一个字节在位置 1 处。

      length - 将获取的部分值的字节长度。

      返回值:

      将从中读取部分 Blob 值的 InputStream。

    6.4. JDBC Clob API

    1. public long length()

      功能:

      获取此 Clob 对象指定的 CLOB 值中的字符数。

      返回值:

      CLOB 的字符长度。

    2. public String getSubString(long pos,int length)

      功能:

      获取此 Clob 对象指定的 CLOB 值中指定子字符串的副本。子字符串开始于位置 pos 处,有 length 个连续字符。

      参数:

      pos - 要提取的子字符串的第一个字符。第一个字符位于位置 1 处。

      length - 要复制的连续字符的数量;length 的值必须大于等于 0 。

      返回值:

      一个 String,它是由此 Clob 对象指定的 CLOB 值中的指定子字符串

    3. public Reader getCharacterStream()

      功能:

      以 java.io.Reader 对象形式(或字符流形式)获取此 Clob 对象指定的 CLOB 值。

      返回值:

      包含 CLOB 数据的 java.io.Reader 对象。

    4. public InputStream getAsciiStream()

      功能:

      以 ascii 流形式获取此 Clob 对象指定的 CLOB 值。

      返回值:

      包含 CLOB 数据的 java.io.InputStream 对象。

    5. public long position(String searchstr,long start)

      功能:

      获取此 Clob 对象表示的 SQL CLOB 值中指定子字符串 searchstr 出现的字符位置。从位置 start 开始搜索。PG兼容模式下未实现。

      参数:

      searchstr - 要搜索的子字符串。

      start - 开始搜索的位置;第一个位置是 1。

      返回值:

      子字符串出现的位置;如果没有出现,则返回 -1;第一个位置是 1。

    6. public long position(Clob searchstr,long start)

      功能:

      获取此 Clob 对象中指定的 Clob 对象 searchstr 出现的字符位置。从位置 start 开始搜索。PG兼容模式下未实现。

      参数:

      searchstr - 要搜索的 Clob 对象。

      start - 开始搜索的位置;第一个位置是 1。

      返回值:

      Clob 对象出现的位置;如果没有出现,则返回 -1;第一个位置是 1。

    7. public int setString(long pos,String str)

      功能:

      在位置 pos 处将给定 Java String 写入此 Clob 对象指定的 CLOB 值中。该字符串将从位置 pos 开始重写 Clob 对象中的现有字节。如果在写入给定字符串时到达 Clob 值的末尾,则将增加 Clob 值的长度,以容纳额外的字符。PG兼容模式下未实现。

      参数:

      pos - 开始写入此 Clob 对象表示的 CLOB 值的位置;第一个位置是 1。

      str - 要写入此 Clob 指定的 CLOB 值中的字符串。

      返回值:

      写入的字符数。

    8. public int setString(long pos,String str,int offset,int len)

      功能:

      将 str 的 len 个字符(从字符 offset 开始)写入此 Clob 表示的 CLOB 值中。该字符串将从位置 pos 开始重写 Clob 对象中的现有字节。如果在写入给定字符串时到达 Clob 值的末尾,则将增加 Clob 值的长度,以容纳额外的字符。PG兼容模式下未实现。

      参数:

      pos - 开始写入此 CLOB 对象的位置;第一个位置是 1。

      str - 要写入此 Clob 对象表示的 CLOB 值中的字符串。

      offset - str 中开始读取要写入字符的偏移量。

      len - 要写入的字符数。

      返回值:

      写入的字符数。

    9. public OutputStream setAsciiStream(long pos)

      功能:

      获取用于将 Ascii 字符写入此 Clob 对象表示的 Clob 值中的流,从位置 pos 处开始。写入流中的字符将从位置 pos 开始重写 Clob 对象中的现有字节。如果在将字符写入流中时到达 Clob 值的末尾,则将增加 Clob 值的长度,以容纳额外的字符。PG兼容模式下未实现。

      参数:

      pos - 开始写入此 CLOB 对象中的位置;第一个位置是 1。

      返回值:

      可以将 ASCII 编码字符写入其中的流。

    10. public Writer setCharacterStream(long pos)

      功能:

      获取用于将 Unicode 字符流写入此 Clob 对象表示的 CLOB 值中(位置 pos 处)的流。写入流中的字符将从位置 pos 开始重写 Clob 对象中的现有字节。如果在将字符写入流中时到达 Clob 值的末尾,则将增加 Clob 值的长度,以容纳额外的字符。PG兼容模式下未实现。

      参数:

      pos - 开始写入 CLOB 值中的位置;第一个位置是 1。

      返回值:

      可将 Unicode 编码字符写入其中的流。

    11. public void truncate(long len)

      功能:

      截取此 Clob 指定的 CLOB 值,使其长度为 len 个字符。

      参数:

      len - CLOB 值应被截取的字符长度。

    12. public void free()

      功能:

      此方法释放 Clob 对象以及它所占用的资源。调用 free 方法后,该对象无效。

    6.5. JDBC SQLXML API

    1. public void free()

      功能:

      此方法关闭此对象并释放其持有的资源。

    2. public InputStream getBinaryStream()

      功能:

      以流的形式获取此 SQLXML 实例指定的 XML 值。

      返回值:

      包含 XML 数据的流。

    3. public OutputStream setBinaryStream()

      功能:

      获取可用于写入此 SQLXML 实例表示的 XML 值的流。

      返回值:

      可以写入数据的流。

    4. public Reader getCharacterStream()

      功能:

      以 java.io.Reader 对象的形式获取此 SQLXML 实例指定的 XML 值。

      返回值:

      包含 XML 数据的流。

    5. public Writer setCharacterStream()

      功能:

      获取用于写入此 SQLXML 实例表示的 XML 值的流。

      返回值:

      可以写入数据的流。

    6. public String getString()

      功能:

      返回此 SQLXML 实例指定的 XML 值的字符串表示形式。

      返回值:

      此 SQLXML 实例指定的 XML 值的字符串表示形式。

    7. public void setString(String value)

      功能:

      将此 SQLXML 实例指定的 XML 值设置为给定的 String 表示形式。

      参数:

      value - XML 值。

    8. public T getSource(Class sourceClass)

      功能:

      返回读取此 SQLXML 实例指定的 XML 值的 Source。Source 用作对 XML 解析器和 XSLT 转换器的输入。

      参数:

      sourceClass - 源的类,或为 null。如果该类为 null,则将返回特定于供应商的 Source 实现。至少支持以下类

      javax.xml.transform.dom.DOMSource - 返回 DOMSource

      javax.xml.transform.sax.SAXSource - 返回 SAXSource

      javax.xml.transform.stax.StAXSource - 返回 StAXSource

      javax.xml.transform.stream.StreamSource - 返回 StreamSource

      返回值:

      读取 XML 值的 Source。

    9. public T setResult(Class resultClass)

      功能:

      返回设置此 SQLXML 实例指定的 XML 值的 Result。

      参数:

      resultClass - 所得的类,或为 null。如果 resultClass 为 null,则将返回特定于供应商的 Result 实现。至少支持以下类:

      javax.xml.transform.dom.DOMResult - 返回 DOMResult

      javax.xml.transform.sax.SAXResult - 返回 SAXResult

      javax.xml.transform.stax.StAXResult - 返回 StAXResult

      javax.xml.transform.stream.StreamResult - 返回 StreamResult

      返回值:

      返回设置 XML 值的 Result。

  • 相关阅读:
    1.docker安装
    软件测试——集成测试篇
    Web开发-GET与POST
    算法通关村-----透析回溯的模版
    Dos的三种攻击类型
    一、Shell编程_5Shell流程控制
    财务福音!用Python+OCR人工智能识别发票自动存入Excel表格保姆级教程
    在idea中创建MyBatis核心配置文件和映射文件的模板、使用模板搭建MyBatis框架
    计算机复习
    interface 接口相关【GO 基础】
  • 原文地址:https://blog.csdn.net/arthemis_14/article/details/126139062