文档

Java™教程
隐藏目录
使用大对象
路径: JDBC 数据库访问
课程: JDBC 基础

使用大对象

BlobClobNClob Java对象的一个重要特点是,您可以在不将它们的所有数据从数据库服务器带到客户端计算机的情况下操作它们。一些实现使用一个定位器(逻辑指针)来表示这些类型的实例,该定位器指向实例所表示的数据库中的对象。由于BLOBCLOBNCLOB SQL对象可能非常大,使用定位器可以显著提高性能。然而,其他实现在客户端计算机上完全实例化大对象。

如果您想将BLOBCLOBNCLOB SQL值的数据带到客户端计算机,可以使用BlobClobNClob Java接口中提供的方法。这些大对象类型对象将它们所表示的对象的数据作为流实例化。

下面介绍了以下主题:

向数据库中添加大对象类型对象

下面摘自ClobSample.addRowToCoffeeDescriptions的代码将一个CLOB SQL值添加到表COFFEE_DESCRIPTIONS中。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("写入的内容如下: " + clobWriter.toString());
      if (this.settings.dbms.equals("mysql")) {
        System.out.println("MySQL,使用setString方法在Clob对象中设置字符串");
        myClob.setString(1, str);
      }
      System.out.println("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("意外异常: " + ex.toString());
    }
  }

以下代码创建了一个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 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);
      }
      // 将内容转换为字符串
      String clobData = sb.toString();
	  // 返回数据。
      return clobData;
	}
  }

以下代码片段创建了一个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();
      // ...

检索CLOB值

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

  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;
  }

以下代码行从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 SQL值,该值由调用该方法的Blob Java对象表示。

释放大对象所持有的资源

BlobClobNClob Java对象在创建它们的事务的持续时间内保持有效。在长时间运行的事务期间,这可能导致应用程序耗尽资源。应用程序可以通过调用它们的free方法释放BlobClobNClob资源。

在以下代码片段中,调用Clob.free方法释放先前创建的Clob对象所持有的资源:

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

上一页: 使用高级数据类型
下一页: 使用SQLXML对象