The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
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. Blob
、Clob
和NClob
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. BLOB
、CLOB
或NCLOB
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. BLOB
、CLOB
或NCLOB
SQL值的数据带到客户端计算机,请使用为此目的提供的BLOB
、CLOB
和NCLOB
Java接口中的方法。These large object type objects materialize the data of the objects they represent as a stream.这些大型对象类型对象将其表示为流的对象的数据具体化。
The following topics are covered:涵盖以下主题:
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
. clobWriter
的Writer
对象),该流用于将字符流写入Clob
java对象myClob
。The 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(); // ...
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_DESCRIPTIONS
的COF_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
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值。
Blob
, Clob
, and NClob
Java objects remain valid for at least the duration of the transaction in which they are created. Blob
、Clob
和NClob
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.Blob
、Clob
和NClob
资源。
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();