使用大对象

BlobClobNClob Java 对象的一个重要功能是您可以操作它们,而不必将其所有数据从数据库服务器带到 Client 端计算机。一些实现通过定位器(逻辑指针)来代表这些类型的实例,该定位器指向该实例所代表的数据库中的对象。因为BLOBCLOBNCLOB SQL 对象可能非常大,所以使用定位符可使性能大大提高。但是,其他实现完全在 Client 端计算机上实现大型对象。

如果要将BLOBCLOBNCLOB SQL 值的数据带到 Client 端计算机,请使用为此 Object 提供的BlobClobNClob Java interface中的方法。这些大型对象类型的对象具体化了它们表示为流的对象的数据。

涵盖以下主题:

将大对象类型的对象添加到数据库

以下来自ClobSample.addRowToCoffeeDescriptions的摘录将CLOB SQL 值添加到表COFFEE_DESCRIPTIONSClob Java 对象myClob包含fileName指定的文件的内容。

public void addRowToCoffeeDescriptions(
    String coffeeName, String fileName)
    throws SQLException {

    PreparedStatement pstmt = null;
    try {
        Clob myClob = this.con.createClob();
        Writer clobWriter = myClob.setCharacterStream(1);
        String str = this.readFile(fileName, clobWriter);
        System.out.println("Wrote the following: " +
            clobWriter.toString());

        if (this.settings.dbms.equals("mysql")) {
            System.out.println(
                "MySQL, setting String in Clob " +
                "object with setString method");
            myClob.setString(1, str);
        }
        System.out.println("Length of Clob: " + myClob.length());

        String sql = "INSERT INTO COFFEE_DESCRIPTIONS " +
                     "VALUES(?,?)";

        pstmt = this.con.prepareStatement(sql);
        pstmt.setString(1, coffeeName);
        pstmt.setClob(2, myClob);
        pstmt.executeUpdate();
    } catch (SQLException sqlex) {
        JDBCTutorialUtilities.printSQLException(sqlex);
    } catch (Exception ex) {
      System.out.println("Unexpected exception: " + ex.toString());
    } finally {
        if (pstmt != null)pstmt.close();
    }
}

下面的行创建一个Clob Java 对象:

Clob myClob = this.con.createClob();

下一行检索一个流(在本例中为名为clobWriterWriter对象),该流用于将字符流写入Clob Java 对象myClob。方法ClobSample.readFile写入此字符流;该流来自String fileName指定的文件。方法参数1表示Writer对象将在Clob值的开头开始写入字符流:

Writer clobWriter = myClob.setCharacterStream(1);

ClobSample.readFile方法逐行读取文件fileName指定的文件,并将其写入writerArg指定的Writer对象:

private String readFile(String fileName, Writer writerArg)
        throws FileNotFoundException, IOException {

    BufferedReader br = new BufferedReader(new FileReader(fileName));
    String nextLine = "";
    StringBuffer sb = new StringBuffer();
    while ((nextLine = br.readLine()) != null) {
        System.out.println("Writing: " + nextLine);
        writerArg.write(nextLine);
        sb.append(nextLine);
    }
    // Convert the content into to a string
    String clobData = sb.toString();

    // Return the data.
    return clobData;
}

以下摘录创建了一个PreparedStatement对象pstmt,该对象将Clob Java 对象myClob插入到COFFEE_DESCRIPTIONS

PreparedStatement pstmt = null;
// ...
String sql = "INSERT INTO COFFEE_DESCRIPTIONS VALUES(?,?)";
pstmt = this.con.prepareStatement(sql);
pstmt.setString(1, coffeeName);
pstmt.setClob(2, myClob);
pstmt.executeUpdate();

检索 CLOB 值

方法ClobSample.retrieveExcerpt从其列值COF_NAME等于coffeeName参数指定的String值的行中检索存储在COFFEE_DESCRIPTIONSCOF_DESC列中的CLOB SQL 值:

public String retrieveExcerpt(String coffeeName, int numChar)
    throws SQLException {

    String description = null;
    Clob myClob = null;
    PreparedStatement pstmt = null;

    try {
        String sql =
            "select COF_DESC " +
            "from COFFEE_DESCRIPTIONS " +
            "where COF_NAME = ?";

        pstmt = this.con.prepareStatement(sql);
        pstmt.setString(1, coffeeName);
        ResultSet rs = pstmt.executeQuery();

        if (rs.next()) {
            myClob = rs.getClob(1);
            System.out.println("Length of retrieved Clob: " +
                myClob.length());
        }
        description = myClob.getSubString(1, numChar);
    } catch (SQLException sqlex) {
        JDBCTutorialUtilities.printSQLException(sqlex);
    } catch (Exception ex) {
        System.out.println("Unexpected exception: " + ex.toString());
    } finally {
        if (pstmt != null) pstmt.close();
    }
    return description;
}

下一行从ResultSet对象rs检索Clob Java 值:

myClob = rs.getClob(1);

下一行从myClob对象检索一个子字符串。子字符串 从值myClob的第一个字符开始,并具有numChar中指定的连续字符数,其中numChar是整数。

description = myClob.getSubString(1, numChar);

添加和检索 BLOB 对象

添加和检索BLOB SQL 对象类似于添加和检索CLOB SQL 对象。使用Blob.setBinaryStream方法检索OutputStream对象,以写入Blob Java 对象(称为方法)表示的BLOB SQL 值。

释放大对象持有的资源

BlobClobNClob Java 对象至少在创建它们的事务期间保持有效。在 Long 期运行的事务中,这可能导致应用程序资源不足。应用程序可以通过调用free方法来释放BlobClobNClob资源。

在以下摘录中,调用方法Clob.free以释放为先前创建的Clob对象保留的资源:

Clob aClob = con.createClob();
int numWritten = aClob.setString(1, val);
aClob.free();