小閣飛空 一池碧映垂楊路 絳云深處 聽盡瀟瀟雨
          At times , people will simply not come through for you in the way you need.Forgive them and move on.
          posts - 212,comments - 87,trackbacks - 0
              在Oracle中,LOB(Large Object,大型對象)類型的字段現在用得越來越多了。因為這種類型的字段,容量大(最多能容納4GB的數據),且一個表中可以有多個這種類型的字段,很靈活,適用于數據量非常大的業務領域(如圖象、檔案等)。而LONG、LONG RAW等類型的字段,雖然存儲容量也不?。蛇_2GB),但由于一個表中只能有一個這樣類型的字段的限制,現在已很少使用了。
              LOB類型分為BLOB和CLOB兩種:BLOB即二進制大型對象(Binary Large Object),適用于存貯非文本的字節流數據(如程序、圖象、影音等)。而CLOB,即字符型大型對象(Character Large Object),則與字符集相關,適于存貯文本型的數據(如歷史檔案、大部頭著作等)。
              下面以程序實例說明通過JDBC操縱Oracle數據庫LOB類型字段的幾種情況。
              先建立如下兩個測試用的數據庫表,Power Designer PD模型如下:

                        

          建表SQL語句為:
          CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB)
          CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)

          一、 CLOB對象的存取

          1、往數據庫中插入一個新的CLOB對象
          public static void clobInsert(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 插入一個空的CLOB對象 */
          stmt.executeUpdate("INSERT INTO TEST_CLOB valueS ('111', EMPTY_CLOB())");
          /* 查詢此CLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
          while (rs.next()) {
          /* 取出此CLOB對象 */
          oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
          /* 向CLOB對象中寫入數據 */
          BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
          BufferedReader in = new BufferedReader(new FileReader(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          2、修改CLOB對象(是在原CLOB對象基礎上進行覆蓋式的修改)
          public static void clobModify(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 查詢CLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
          while (rs.next()) {
          /* 獲取此CLOB對象 */
          oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
          /* 進行覆蓋式修改 */
          BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
          BufferedReader in = new BufferedReader(new FileReader(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          3、替換CLOB對象(將原CLOB對象清除,換成一個全新的CLOB對象)
          public static void clobReplace(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 清空原CLOB對象 */
          stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='111'");
          /* 查詢CLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
          while (rs.next()) {
          /* 獲取此CLOB對象 */
          oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
          /* 更新數據 */
          BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
          BufferedReader in = new BufferedReader(new FileReader(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          4、CLOB對象讀取
          public static void clobRead(String outfile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 查詢CLOB對象 */
          ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID='111'");
          while (rs.next()) {
          /* 獲取CLOB對象 */
          oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
          /* 以字符形式輸出 */
          BufferedReader in = new BufferedReader(clob.getCharacterStream());
          BufferedWriter out = new BufferedWriter(new FileWriter(outfile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          out.close();
          in.close();
          }
          } catch (Exception ex) {
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          二、 BLOB對象的存取

          1、 向數據庫中插入一個新的BLOB對象
          public static void blobInsert(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 插入一個空的BLOB對象 */
          stmt.executeUpdate("INSERT INTO TEST_BLOB valueS ('222', EMPTY_BLOB())");
          /* 查詢此BLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
          while (rs.next()) {
          /* 取出此BLOB對象 */
          oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
          /* 向BLOB對象中寫入數據 */
          BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
          BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          2、修改BLOB對象(是在原BLOB對象基礎上進行覆蓋式的修改)
          public static void blobModify(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 查詢BLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
          while (rs.next()) {
          /* 取出此BLOB對象 */
          oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
          /* 向BLOB對象中寫入數據 */
          BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
          BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          3、替換BLOB對象(將原BLOB對象清除,換成一個全新的BLOB對象)
          public static void blobReplace(String infile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 清空原BLOB對象 */
          stmt.executeUpdate("UPDATE TEST_BLOB SET BLOBCOL=EMPTY_BLOB() WHERE ID='222'");
          /* 查詢此BLOB對象并鎖定 */
          ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
          while (rs.next()) {
          /* 取出此BLOB對象 */
          oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
          /* 向BLOB對象中寫入數據 */
          BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
          BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {
          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }
          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

          4、BLOB對象讀取
          public static void blobRead(String outfile) throws Exception
          {
          /* 設定不自動提交 */
          boolean defaultCommit = conn.getAutoCommit();
          conn.setAutoCommit(false);
          try {
          /* 查詢BLOB對象 */
          ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222'");
          while (rs.next()) {
          /* 取出此BLOB對象 */
          oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
          /* 以二進制形式輸出 */
          BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));
          BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());
          int c;
          while ((c=in.read())!=-1) {
          out.write(c);
          }
          in.close();
          out.close();
          }
          /* 正式提交 */
          conn.commit();
          } catch (Exception ex) {

          /* 出錯回滾 */
          conn.rollback();
          throw ex;
          }

          /* 恢復原提交狀態 */
          conn.setAutoCommit(defaultCommit);
          }

              觀察上述程序對LOB類型字段的存取,我們可以看出,較之其它類型字段,有下面幾個顯著不同的特點:

          一是必須取消自動提交。

              存取操作開始前,必須用setAutoCommit(false)取消自動提交。其它類型字段則無此特殊要求。這是因為存取LOB類型字段時,通常要進行多次操作可以完成。不這樣的話,Oracle將拋出“讀取違反順序”的錯誤。

          二是插入方式不同。

              LOB數據不能象其它類型數據一樣直接插入(INSERT)。插入前必須先插入一個空的LOB對象,CLOB類型的空對象為EMPTY_CLOB(),BLOB類型的空對象為EMPTY_BLOB()。之后通過SELECT命令查詢得到先前插入的記錄并鎖定,繼而將空對象修改為所要插入的LOB對象。

          三是修改方式不同。

              其它類型的字段修改時,用UPDATE … SET…命令即可。而LOB類型字段,則只能用SELECT … FOR UPDATE命令將記錄查詢出來并鎖定,然后才能修改。且修改也有兩種改法:一是在原數據基礎上的修改(即覆蓋式修改),執行SELECT … FOR UPDATE后再改數據;二是替換(先將原數據清掉,再修改),先執行UPDATE命令將LOB字段之值設為空的LOB對象,然后進行第一種改法。建議使用替換的方法,以實現與其它字段UPDATE操作后一樣的效果。

          四是存取時應使用由數據庫JDBC驅動程序提供的LOB操作類。

              對于Oracle數據庫,應使用oracle.sql.CLOB和oracle.sql.BLOB。不使用由數據庫JDBC驅動程序提供的LOB類時,程序運行時易于出現“抽象方法調用”的錯誤,這是因為JDBC所定義的java.sql.Clob與java.sql.Blob接口,其中的一些方法并未在數據庫廠家提供的驅動程序中真正實現。

          五是存取手段與文件操作相仿。

              對于BLOB類型,應用InputStream/OutputStream類,此類不進行編碼轉換,逐個字節存取。oracle.sql.BLOB類相應提供了getBinaryStream()和getBinaryOutputStream()兩個方法,前一個方法用于讀取Oracle的BLOB字段,后一個方法用于將數據寫入Oracle的BLOB字段。
              對于CLOB類型,應用Reader/Writer類,此類進行編碼轉換。oracle.sql.CLOB類相應提供了getCharacterStream()和getCharacterOutputStream()兩個方法,前一個方法用于讀取Oracle的CLOB字段,后一個方法用于將數據寫入Oracle的CLOB字段。
              需要說明的是,為了大幅提高程序執行效率,對BLOB/CLOB字段的讀寫操作,應該使用緩沖操作類(帶Buffered前綴),即:BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter。例程中全部使用了緩沖操作類。

              小結:通過JDBC操縱Oracle數據庫的LOB字段,不外乎插入、修改、替換、讀取四種方式,掌握起來并不難。在實際操作中要注意上面所說的幾點,結合閱讀例程源程序,用戶會很快明白LOB類型字段的使用的,也必將領悟到這種類型字段的妙處!
          posted on 2005-11-16 15:04 瀟瀟雨 閱讀(221) 評論(0)  編輯  收藏 所屬分類: JAVA 、Database
          主站蜘蛛池模板: 南川市| 安康市| 望都县| 石泉县| 利津县| 龙山县| 福鼎市| 十堰市| 文登市| 应城市| 高州市| 灵石县| 壶关县| 昌邑市| 宁远县| 汉源县| 绥德县| 澜沧| 白水县| 贵德县| 万安县| 柳河县| 秭归县| 海林市| 宁德市| 宜章县| 莲花县| 武清区| 平江县| 嘉鱼县| 吉林市| 英山县| 银川市| 苏尼特右旗| 苏尼特左旗| 新竹市| 云浮市| 贵阳市| 容城县| 宁蒗| 东台市|