随笔-47  评论-14  文章-0  trackbacks-0

                                               字符大对象Blob

Blob对象是SQL BlobJava语言映射。SQL Blob是一个内置类型,它可以将一个二进制大对象保存在数据库中。接口ResultSetCallableStatementPreparedStatement中的方法允许程序员使用与访问SQL 92内置类型同样的方式来访问SQL 99类型BLOB

在标准实现中,JDBC驱动程序在后台使用SQL类型LOCATOR(BLOB)来实现Blob接口。LOCATOR(BLOB)指向保存在数据库服务器上的SQL BLOB值,而且这些操作作用在这个LOCATOR(定位器)上与作用在BLOB值本身有同样的结果。这意味着用户可以在一个Blob实例上执行操作而不必将这个BLOB数据物化到用户上,这将显著的提高性能。因为驱动程序在后台使用LOCATOR(BLOB),所以它的使用对程序员是完全透明的。

Blob实例的标准行为一直保持有效,直到这个事务(创建一个Blob的事务)执行了提交或者回滚操作。

1、创建Blob对象

下面的代码说明了如何创建一个Blob对象,其中stmt是一个Statement对象:

Statement stmt = con..createStatement(ResultSet.TYPE_INSENSITIVE,

ResultSet.CONCUR_READ_ONLY);

ResultSet rs = stmt.excuteQuery(“SELECT DATA  FROM  TABLE 1”);

If (rs.next()){

rs.first();

Blob blob=rs.getBlob(“DATA”);

}

变量blob包含一个指向BLOB值的逻辑指针,该BLOB值保存在结果集rs的第一行的DATA列中。即使变量blob实际上并不包含BLOB值中的数值,应用程序在blob上执行操作仍然像在实际的数据上执行一样。即应用程序在blob上所作的任何操作都会对表中的BLOB值起作用。

2、物化BLOB数据

开发人员可以在Blob对象上调用JDBC API中的方法,就像这些方法直接在该对象所指向的SQL BLOB上执行操作一样。然而,如果想在BLOB数据上执行操作,就必须首先将BLOB数据物化到客户。Blob接口提供了两个方法来物化BLOB数据:getBinaryStream,这个方法将BLOB数据物化为一个输入流;getBytes,这个方法将BLOB值得一部分或者全部物化为一个字节数组。下面的代码说明了如何将Blob所指向的BLOB值得全部物化为一个输入流: 

java.io.InputStream in = blob.getBinaryStream();

byte b;

while((b = in.read()) >-1){

System.out.println(b);

}

接下来的代码同样物化了blob所指向的BLOB值得所有数据,但是它产生的是字节数组而不是输入流。

long len = blob.length();

byte [] data = blob.getBytes(1,len);

for(int i=0;i<len;i++){

    byte b = data[i];

    System.out.println(b);

}

变量data复制了blob所指向的BLOB值的所有字节。这是因为传递给方法getBytes的参数值说明了整个BLOB值:第一个参数表示从第一个字节开始返回字节,第二个参数说明它返回的字节长度是BLOB值的长度。

需要说明的是,因为SQLJava语言之间的不同,一个BLOB值得第一个字节在位置1,而Java数组的第一个元素的索引是0。

3、存储Blob

若要在数据库中存储Blob值,应用程序可以把它作为一个参数传递给PreparedStatement的方法setBlob。下面的代码就实现了这个功能:

Blob stats = rs.getBlob(“STATS”);

PreparedStatement pstmt= con.preparedStatement( “UPDATE SIGHTINGS SET MEAS= ? WHERE  AREA = ‘BEIJING’ ”);

pstmt.setBlob(1,stats);

pstmt.excuteUpdate();

4、发现Blob对象中的模式如果一个Blob对象包含一个给定的字节集合,应用程序可以使用方法position的两个方法来找到它。其中一个方法搜索一个给定的字节数组,而另一个在一个Blob对象中搜索一个给定的Blob对象。如果发现一个匹配的结果,则返回该模式字节的起始位置。

5、修改Blob对象的方法

JDBC 3.0 API中新增的方法setBytessetBinaryStream允许应用程序对Blob对象进行修改。

方法setBytes有两个方法来向Blob对象添加数据。其中一个方法增加给定的字节数组的全部内容,而另一个方法增加给定字节数组的特定部分。两个方法都使用一个参数说明向Blob对象插入数据的起始位置。例如,下面的代码段在一个Blob对象blob1的第一个字节处写入整个字节数组bytes。在这种情况下,bytes包含了Blob对象blob的所有字节,因此执行的结果是blob2被写入了blob1的起始处。需要注意的是如果blob2的长度是1024字节,那么blob21024各字节将覆盖blob1的开头的1024各字节。

byte [] bytes = blob2.getBytes(1,blob2.length());

blob.setBytes(1,bytes,0,512);

下面的代码段说明如何仅仅向Blob对象加入一个字节数组的特定部分。在这种情况下,方法setBytes接受两个附加的参数来说明需要增加字节数组的哪一个部分。其中一个参数指明了这个字节数组的起始偏移量,另一个参数说明这个字节数组包含多少个连续的字节。

byte [] bytes={……};

blob.setBytes(1,bytes,0,512); 

除了可以向Blob对象增加字节之外,Blob接口还提供了删除字节的方法。方法truncate接受一个字节数目作为一个参数并且根据这个数目来缩短Blob对象。

6、定位器和更新

在标准实现中,指向SQL BLOBBlob对象使用了SQL LOCATOR类型。定位器(locator)是一个指向保存在数据库中的BLOB值的指针,而DBMS如何更新一个作为定位器实现的对象则依赖于具体的数据库。某些DBMS会更新表中的BLOB值,而另一些则仅仅更新BLOB值的一个副本,并不改变数据库中的值。在后一种情况下,应用程序必须直接更新BLOb值。

为了发现DBMS是如何更新BLOB值的,应用程序可以调用DatabaseMetaData的方法locatorsUpdateCopy。如果这个方法返回true,则应用程序必须自己更新数据库中的BLOB值。下面的代码显示了这个过程:首先从rs取回Blob对象,然后把它的值改为字节数据val的值。如果方法locatorsUpdateCopy返回true,那么它随后执行一个PreparedStatement对象来更新数据库中的值。如果方法locatorsUpdateCopy返回false,代码什么也不用做,因为数据库中的值已经被更新过了。

byte [] val ={0,1,2,3,4};

Blob data =rs.getBlob(“DATA”);

int numWritten = data.setBytes(1,val);

if (dbmd.locatorUpdateCopy() == true){

PreparedStatement pstmt= con . preparedStatement( “UPDATE statistics SET DATA = ? WHERE REGION = ‘BEIJING’ “);

pstmt.setBlob(“DATA”,data);

pstmt.executeUpdate();

}

 

                                          字符大对象Clob

1、创建Blob对象

下面的代码段说明了如何创建一个Clob对象,其中rs是一个ResultSet对象:Clob clob = rs.getClob(1); 变量clob现在可以被用于在CLOB值上执行操作,而假设这CLOB值保存在结果集rs的第一列中。

2、物化Clob数据

和物化Blob的方式一样。不过Clob接口提供了三种方法达到将CLOB为一个Java对象的形式保存在客户的内存中。

    使用getAsiiStream把CLOB值物化为一个包含Ascii字节的字符流。

Clob notes = rs.getClob(“NOTES”);

java.io.InputStream in = notes.getAsciiStream();

byte b = in.read();

    使用getCharacterStream把CLOB值物化为一个Unicode字符流。

Clob notes = rs.getClob(“NOTES”);

java.io.Reader reader = notes.getCharacterStream();

int c = reader.read();

    使用getSubString将CLOB值的全部或者部分化为一个String对象。

Clob notes = rs.getClob(4);

String substring= notes.getSubString(10,5);

或者

long len =notes.length();

String substring = notes.getSubString(1,(int)len);

3、存储、更新Clob对象

和存储、更新Blob对象类似。

posted on 2005-11-20 00:19 Stephen 阅读(699) 评论(0)  编辑  收藏 所属分类: DB

只有注册用户登录后才能发表评论。


网站导航: