JAVA處理Blob大對象

 Blob對象是SQL Blob的Java語言映射。SQL Blob是一個內置類型,它能夠將一個二進制大對象保存在數據庫中。接口ResultSet、CallableStatement和PreparedStatement中的方法容許程序員使用與訪問SQL 92內置類型一樣的方式來訪問SQL 99類型BLOB。
 在標準實現中,JDBC驅動程序在後臺使用SQL類型LOCATOR(BLOB)來實現Blob接口。LOCATOR(BLOB)指向保存在數據庫服務器上的SQL BLOB值,並且這些操做做用在這個LOCATOR(定位器)上與做用在BLOB值自己有一樣的結果。
 意味着用戶能夠在一個Blob實例上執行操做而沒必要將這個BLOB數據物化到用戶上,這將顯著的提升性能。由於驅動程序在後臺使用LOCATOR(BLOB),因此它的使用對程序員是徹底透明的。java

 

Blob實例的標準行爲一直保持有效,直到這個事務(建立一個Blob的事務)執行了提交或者回滾操做。程序員


一、建立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值起做用。性能

 

二、物化BLOB數據spa

  開發人員能夠在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值的長度。
須要說明的是,由於SQL和Java語言之間的不一樣,一個BLOB值得第一個字節在位置1,而Java數組的第一個元素的索引是0。索引

 

三、存儲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();

FileInputStream fis1 = new FileInputStream("D:/aa.jpg");
pstmt.setBinaryStream(1, fis1, fis1.available());
  
四、發現Blob對象中的模式
若是一個Blob對象包含一個給定的字節集合,應用程序可使用方法
position的兩個方法來找到它。其中一個方法搜索一個給定的字節數組,而另外一個在一個Blob對象中搜索一個給定的Blob對象。若是發現一個匹配的結果,則返回該模式字節的起始位置。

 

五、修改Blob對象的方法
JDBC 3.0 API中新增的方法setBytes和setBinaryStream容許應用程序對Blob對象進行修改。

方法setBytes有兩個方法來向Blob對象添加數據。其中一個方法增長給定的字節數組的所有內容,而另外一個方法增長給定字節數組的特定部分。兩個方法都使用一個參數說明向Blob對象插入數據的起始位置。例如,下面的代碼段在一個Blob對象blob1的第一個字節處寫入整個字節數組bytes。在這種狀況下,bytes包含了Blob對象blob的全部字節,所以執行的結果是blob2被寫入了blob1的起始處。須要注意的是若是blob2的長度是1024字節,那麼blob2的1024各字節將覆蓋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對象。

 

六、定位器和更新
在標準實現中,指向SQL BLOB的Blob對象使用了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();}

相關文章
相關標籤/搜索