隨筆-47  評(píng)論-14  文章-0  trackbacks-0

                                                         字符大對(duì)象Blob

          Blob對(duì)象是SQL BlobJava語(yǔ)言映射。SQL Blob是一個(gè)內(nèi)置類型,它可以將一個(gè)二進(jìn)制大對(duì)象保存在數(shù)據(jù)庫(kù)中。接口ResultSetCallableStatementPreparedStatement中的方法允許程序員使用與訪問(wèn)SQL 92內(nèi)置類型同樣的方式來(lái)訪問(wèn)SQL 99類型BLOB

          在標(biāo)準(zhǔn)實(shí)現(xiàn)中,JDBC驅(qū)動(dòng)程序在后臺(tái)使用SQL類型LOCATOR(BLOB)來(lái)實(shí)現(xiàn)Blob接口。LOCATOR(BLOB)指向保存在數(shù)據(jù)庫(kù)服務(wù)器上的SQL BLOB值,而且這些操作作用在這個(gè)LOCATOR(定位器)上與作用在BLOB值本身有同樣的結(jié)果。這意味著用戶可以在一個(gè)Blob實(shí)例上執(zhí)行操作而不必將這個(gè)BLOB數(shù)據(jù)物化到用戶上,這將顯著的提高性能。因?yàn)轵?qū)動(dòng)程序在后臺(tái)使用LOCATOR(BLOB),所以它的使用對(duì)程序員是完全透明的。

          Blob實(shí)例的標(biāo)準(zhǔn)行為一直保持有效,直到這個(gè)事務(wù)(創(chuàng)建一個(gè)Blob的事務(wù))執(zhí)行了提交或者回滾操作。

          1、創(chuàng)建Blob對(duì)象

          下面的代碼說(shuō)明了如何創(chuàng)建一個(gè)Blob對(duì)象,其中stmt是一個(gè)Statement對(duì)象:

          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包含一個(gè)指向BLOB值的邏輯指針,該BLOB值保存在結(jié)果集rs的第一行的DATA列中。即使變量blob實(shí)際上并不包含BLOB值中的數(shù)值,應(yīng)用程序在blob上執(zhí)行操作仍然像在實(shí)際的數(shù)據(jù)上執(zhí)行一樣。即應(yīng)用程序在blob上所作的任何操作都會(huì)對(duì)表中的BLOB值起作用。

          2、物化BLOB數(shù)據(jù)

          開(kāi)發(fā)人員可以在Blob對(duì)象上調(diào)用JDBC API中的方法,就像這些方法直接在該對(duì)象所指向的SQL BLOB上執(zhí)行操作一樣。然而,如果想在BLOB數(shù)據(jù)上執(zhí)行操作,就必須首先將BLOB數(shù)據(jù)物化到客戶。Blob接口提供了兩個(gè)方法來(lái)物化BLOB數(shù)據(jù):getBinaryStream,這個(gè)方法將BLOB數(shù)據(jù)物化為一個(gè)輸入流;getBytes,這個(gè)方法將BLOB值得一部分或者全部物化為一個(gè)字節(jié)數(shù)組。下面的代碼說(shuō)明了如何將Blob所指向的BLOB值得全部物化為一個(gè)輸入流: 

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

          byte b;

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

          System.out.println(b);

          }

          接下來(lái)的代碼同樣物化了blob所指向的BLOB值得所有數(shù)據(jù),但是它產(chǎn)生的是字節(jié)數(shù)組而不是輸入流。

          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復(fù)制了blob所指向的BLOB值的所有字節(jié)。這是因?yàn)閭鬟f給方法getBytes的參數(shù)值說(shuō)明了整個(gè)BLOB值:第一個(gè)參數(shù)表示從第一個(gè)字節(jié)開(kāi)始返回字節(jié),第二個(gè)參數(shù)說(shuō)明它返回的字節(jié)長(zhǎng)度是BLOB值的長(zhǎng)度。

          需要說(shuō)明的是,因?yàn)?/SPAN>SQLJava語(yǔ)言之間的不同,一個(gè)BLOB值得第一個(gè)字節(jié)在位置1,而Java數(shù)組的第一個(gè)元素的索引是0。

          3、存儲(chǔ)Blob

          若要在數(shù)據(jù)庫(kù)中存儲(chǔ)Blob值,應(yīng)用程序可以把它作為一個(gè)參數(shù)傳遞給PreparedStatement的方法setBlob。下面的代碼就實(shí)現(xiàn)了這個(gè)功能:

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

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

          pstmt.setBlob(1,stats);

          pstmt.excuteUpdate();

          4、發(fā)現(xiàn)Blob對(duì)象中的模式如果一個(gè)Blob對(duì)象包含一個(gè)給定的字節(jié)集合,應(yīng)用程序可以使用方法position的兩個(gè)方法來(lái)找到它。其中一個(gè)方法搜索一個(gè)給定的字節(jié)數(shù)組,而另一個(gè)在一個(gè)Blob對(duì)象中搜索一個(gè)給定的Blob對(duì)象。如果發(fā)現(xiàn)一個(gè)匹配的結(jié)果,則返回該模式字節(jié)的起始位置。

          5、修改Blob對(duì)象的方法

          JDBC 3.0 API中新增的方法setBytessetBinaryStream允許應(yīng)用程序?qū)?/SPAN>Blob對(duì)象進(jìn)行修改。

          方法setBytes有兩個(gè)方法來(lái)向Blob對(duì)象添加數(shù)據(jù)。其中一個(gè)方法增加給定的字節(jié)數(shù)組的全部?jī)?nèi)容,而另一個(gè)方法增加給定字節(jié)數(shù)組的特定部分。兩個(gè)方法都使用一個(gè)參數(shù)說(shuō)明向Blob對(duì)象插入數(shù)據(jù)的起始位置。例如,下面的代碼段在一個(gè)Blob對(duì)象blob1的第一個(gè)字節(jié)處寫入整個(gè)字節(jié)數(shù)組bytes。在這種情況下,bytes包含了Blob對(duì)象blob的所有字節(jié),因此執(zhí)行的結(jié)果是blob2被寫入了blob1的起始處。需要注意的是如果blob2的長(zhǎng)度是1024字節(jié),那么blob21024各字節(jié)將覆蓋blob1的開(kāi)頭的1024各字節(jié)。

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

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

          下面的代碼段說(shuō)明如何僅僅向Blob對(duì)象加入一個(gè)字節(jié)數(shù)組的特定部分。在這種情況下,方法setBytes接受兩個(gè)附加的參數(shù)來(lái)說(shuō)明需要增加字節(jié)數(shù)組的哪一個(gè)部分。其中一個(gè)參數(shù)指明了這個(gè)字節(jié)數(shù)組的起始偏移量,另一個(gè)參數(shù)說(shuō)明這個(gè)字節(jié)數(shù)組包含多少個(gè)連續(xù)的字節(jié)。

          byte [] bytes={……};

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

          除了可以向Blob對(duì)象增加字節(jié)之外,Blob接口還提供了刪除字節(jié)的方法。方法truncate接受一個(gè)字節(jié)數(shù)目作為一個(gè)參數(shù)并且根據(jù)這個(gè)數(shù)目來(lái)縮短Blob對(duì)象。

          6、定位器和更新

          在標(biāo)準(zhǔn)實(shí)現(xiàn)中,指向SQL BLOBBlob對(duì)象使用了SQL LOCATOR類型。定位器(locator)是一個(gè)指向保存在數(shù)據(jù)庫(kù)中的BLOB值的指針,而DBMS如何更新一個(gè)作為定位器實(shí)現(xiàn)的對(duì)象則依賴于具體的數(shù)據(jù)庫(kù)。某些DBMS會(huì)更新表中的BLOB值,而另一些則僅僅更新BLOB值的一個(gè)副本,并不改變數(shù)據(jù)庫(kù)中的值。在后一種情況下,應(yīng)用程序必須直接更新BLOb值。

          為了發(fā)現(xiàn)DBMS是如何更新BLOB值的,應(yīng)用程序可以調(diào)用DatabaseMetaData的方法locatorsUpdateCopy。如果這個(gè)方法返回true,則應(yīng)用程序必須自己更新數(shù)據(jù)庫(kù)中的BLOB值。下面的代碼顯示了這個(gè)過(guò)程:首先從rs取回Blob對(duì)象,然后把它的值改為字節(jié)數(shù)據(jù)val的值。如果方法locatorsUpdateCopy返回true,那么它隨后執(zhí)行一個(gè)PreparedStatement對(duì)象來(lái)更新數(shù)據(jù)庫(kù)中的值。如果方法locatorsUpdateCopy返回false,代碼什么也不用做,因?yàn)閿?shù)據(jù)庫(kù)中的值已經(jīng)被更新過(guò)了。

          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();

          }

           

                                                    字符大對(duì)象Clob

          1、創(chuàng)建Blob對(duì)象

          下面的代碼段說(shuō)明了如何創(chuàng)建一個(gè)Clob對(duì)象,其中rs是一個(gè)ResultSet對(duì)象:Clob clob = rs.getClob(1); 變量clob現(xiàn)在可以被用于在CLOB值上執(zhí)行操作,而假設(shè)這CLOB值保存在結(jié)果集rs的第一列中。

          2、物化Clob數(shù)據(jù)

          和物化Blob的方式一樣。不過(guò)Clob接口提供了三種方法達(dá)到將CLOB為一個(gè)Java對(duì)象的形式保存在客戶的內(nèi)存中。

              使用getAsiiStream把CLOB值物化為一個(gè)包含Ascii字節(jié)的字符流。

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

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

          byte b = in.read();

              使用getCharacterStream把CLOB值物化為一個(gè)Unicode字符流。

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

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

          int c = reader.read();

              使用getSubString將CLOB值的全部或者部分化為一個(gè)String對(duì)象。

          Clob notes = rs.getClob(4);

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

          或者

          long len =notes.length();

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

          3、存儲(chǔ)、更新Clob對(duì)象

          和存儲(chǔ)、更新Blob對(duì)象類似。

          posted on 2005-11-20 00:19 Stephen 閱讀(716) 評(píng)論(0)  編輯  收藏 所屬分類: DB
          主站蜘蛛池模板: 双鸭山市| 巴彦县| 仙游县| 达尔| 普宁市| 宁陵县| 休宁县| 腾冲县| 桐乡市| 陇南市| 高阳县| 邻水| 鄯善县| 富顺县| 瓮安县| 健康| 襄汾县| 林甸县| 平陆县| 元江| 姜堰市| 贵德县| 鄂温| 顺义区| 怀集县| 桑植县| 永新县| 沙田区| 襄垣县| 易门县| 闵行区| 班玛县| 宁安市| 武定县| 漳州市| 六枝特区| 孟村| 朝阳市| 长寿区| 故城县| 肇庆市|