Documentation

The Java™ Tutorials
Hide TOC
Using Large Objects使用大型对象
Trail: JDBC Database Access
Lesson: JDBC Basics

Using Large Objects使用大型对象

An important feature of Blob, Clob, and NClob Java objects is that you can manipulate them without having to bring all of their data from the database server to your client computer. BlobClobNClob Java对象的一个重要特性是,您可以操纵它们,而不必将它们的所有数据从数据库服务器带到客户端计算机。Some implementations represent an instance of these types with a locator (logical pointer) to the object in the database that the instance represents. 一些实现使用指向实例所表示的数据库中的对象的定位器(逻辑游标)来表示这些类型的实例。Because a BLOB, CLOB, or NCLOB SQL object may be very large, the use of locators can make performance significantly faster. 由于BLOBCLOBNCLOB SQL对象可能非常大,因此使用定位器可以显著提高性能。However, other implementations fully materialize large objects on the client computer.但是,其他实现在客户端计算机上完全具体化大型对象。

If you want to bring the data of a BLOB, CLOB, or NCLOB SQL value to the client computer, use methods in the Blob, Clob, and NClob Java interfaces that are provided for this purpose. 如果要将BLOBCLOBNCLOB SQL值的数据带到客户端计算机,请使用为此目的提供的BLOBCLOBNCLOB Java接口中的方法。These large object type objects materialize the data of the objects they represent as a stream.这些大型对象类型对象将其表示为流的对象的数据具体化。

The following topics are covered:涵盖以下主题:

Adding Large Object Type Object to Database向数据库添加大型对象类型对象

The following excerpt from ClobSample.addRowToCoffeeDescriptions adds a CLOB SQL value to the table COFFEE_DESCRIPTIONS. 以下摘自ClobSample.addRowToCoffeeDescriptions的内容将CLOB SQL值添加到表COFFEE_DESCRIPTIONS中。The Clob Java object myClob contains the contents of the file specified by fileName.Clob Java对象myClob包含fileName指定的文件内容。

public void addRowToCoffeeDescriptions(String coffeeName,
                                         String fileName) throws SQLException {
    String sql = "INSERT INTO COFFEE_DESCRIPTIONS VALUES(?,?)";
    Clob myClob = this.con.createClob();
    try (PreparedStatement pstmt = this.con.prepareStatement(sql);
      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());
      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());
    }
  }

The following line creates a Clob Java object:以下行创建Clob Java对象:

Clob myClob = this.con.createClob();

The following line retrieves a stream (in this case a Writer object named clobWriter) that is used to write a stream of characters to the Clob Java object myClob. 下一行检索一个流(在本例中是一个名为clobWriterWriter对象),该流用于将字符流写入Clobjava对象myClobThe method ClobSample.readFile writes this stream of characters; the stream is from the file specified by the String fileName. 方法ClobSample.readFile写入此字符流;流来自字符串文件名指定的文件。The method argument 1 indicates that the Writer object will start writing the stream of characters at the beginning of the Clob value:方法参数1表示Writer对象将在Clob值的开头开始写入字符流:

Writer clobWriter = myClob.setCharacterStream(1);

The ClobSample.readFile method reads the file line-by-line specified by the file fileName and writes it to the Writer object specified by writerArg:ClobSample.readFile方法逐行读取文件名指定的文件,并将其写入writerArg指定的Writer对象:

private String readFile(String fileName, Writer writerArg) throws IOException {
    try (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;
	}
  }

The following excerpt creates a PreparedStatement object pstmt that inserts the Clob Java object myClob into COFFEE_DESCRIPTIONS:以下摘录创建了一个PreparedStatement对象pstmt,该对象将Clob Java对象myClob插入到COFFEE_DESCRIPTIONS中:

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

Retrieving CLOB Values检索CLOB值

The method ClobSample.retrieveExcerpt retrieves the CLOB SQL value stored in the COF_DESC column of COFFEE_DESCRIPTIONS from the row whose column value COF_NAME is equal to the String value specified by the coffeeName parameter:方法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;
    String sql = "select COF_DESC from COFFEE_DESCRIPTIONS where COF_NAME = ?";

    try (PreparedStatement 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());
    }
    return description;
  }

The following line retrieves the Clob Java value from the ResultSet object rs:以下行从ResultSet对象rs检索Clob Java值:

myClob = rs.getClob(1);

The following line retrieves a substring from the myClob object. 下一行从myClob对象检索子字符串。The substring begins at the first character of the value of myClob and has up to the number of consecutive characters specified in numChar, where numChar is an integer.子字符串从myClob值的第一个字符开始,最多包含numChar中指定的连续字符数,其中numChar是一个整数。

description = myClob.getSubString(1, numChar);

Adding and Retrieving BLOB Objects添加和检索BLOB对象

Adding and retrieving BLOB SQL objects is similar to adding and retrieving CLOB SQL objects. 添加和检索BLOB SQL对象与添加和检索CLOB SQL对象类似。Use the Blob.setBinaryStream method to retrieve an OutputStream object to write the BLOB SQL value that the Blob Java object (which called the method) represents.使用Blob.setBinaryStream方法检索OutputStream对象,以写入Blob Java对象(称为方法)表示的Blob SQL值。

Releasing Resources Held by Large Objects释放大型对象所持有的资源

Blob, Clob, and NClob Java objects remain valid for at least the duration of the transaction in which they are created. BlobClobNClob Java对象至少在创建它们的事务期间保持有效。This could potentially result in an application running out of resources during a long running transaction. 这可能会导致应用程序在长时间运行的事务中耗尽资源。Applications may release Blob, Clob, and NClob resources by invoking their free method.应用程序可以通过调用其空闲方法来释放BlobClobNClob资源。

In the following excerpt, the method Clob.free is called to release the resources held for a previously created Clob object:在以下摘录中,调用了Clob.free方法来释放为先前创建的Clob对象保留的资源:

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

Previous page: Using Advanced Data Types
Next page: Using SQLXML Objects