tbwshc

          Oracle 的Blob使用小結(jié)

          Oracle 的Blob

          Oracle的Lobs的流處理方式與Long等對象的Stream方式不一樣,沒有Long的諸多限制;只要保持連接,就能通過blob對象正確讀取對象。
          有兩種方式可以讀取Blob:
          1.直接使用ps.getBinaryStream()的方法得到流對象
          2.使用getBlob得到blob,然后通過blob的方法提供的getBinaryStream(),getBytes() 訪問blob的數(shù)據(jù)。
          這兩種方法都可以在rs.close之后正確獲取數(shù)據(jù)。(在spring 的JdbcTemplet環(huán)境下,該rs理論上被JdbcTemplet自動關(guān)閉;從數(shù)據(jù)庫連接來看,連接也正確關(guān)閉了)。

          使用Blob的好處是,按需獲取Blob對象。而且可以多次通過blob.getBinaryStream得到對象。且Blob返回的對象可以使用mark/reset方法反復訪問。且連接狀態(tài)正常。
          使用blob得到InputStream,可以調(diào)用close()接口,也可以不調(diào)用該接口,tb在連接關(guān)閉時將自動關(guān)閉該連接。最好調(diào)用close()釋放資源。

          c3p0的setBlob(pos,InputStream)接口不能正常工作。

          寫入或更新Blob時,可以使用ps.setBinaryStream();調(diào)用此接口后,in對象到文件尾(在把stream寫入blob后,不能要再調(diào)用in.close()關(guān)閉文件,否則報錯)。
          也可以使用setBlob(pos,Blob)方法來寫入或更新Blob字段;但是注意的是,無論是以blob還是blob.getBinaryStream的方式,都不能自己更新自己,否則死鎖。

          使用spring讀取blob的示例程序:
                      String sql = "select photo from my_photoes where id='test2' and photo is not null and rownum<2 ";
          BLOB blob= (BLOB) simpleDao.queryForObject(sql,Blob.class);       
          InputStream in = blob.getBinaryStream();
          String filename = "./test/dao/pic" + 1+ ".gif";
          BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename));

                      /* 需oracle的BLOB支持。效率可能會高些,但是空間上會有些浪費
          byte[] b = new byte[blob.getBufferSize()];                //blob必須為oracle.sql.BLOB時才可調(diào)getBufferSize方法; 與java.sql.Blob區(qū)別。
          System.out.println("bufferSize="+b.length);            //32k左右,用這種方式讀取文件會有一點空間的浪費。
          int len=-1;
          while ((len = in.read(b)) != -1) {
          out.write(b);
          }
                      */

                      /*   純jdbc方法:
                          nt b;
               while ((b = in.read()) != -1) {
              out.write(b);
               }
                      */

          in.close();
          out.close();



          http://hi.baidu.com/hexiong/blog/item/34d7b2b7f9b3e8f431add103.html  其他參考
          BLOB處理遇到的問題:
          1.用spring的模板類來處理blob時,遇到大文件時,流會異常關(guān)閉。解決辦法,使用oracle的本地連接來獲取blob流,如下:
              public boolean queryForBlobStream(String sql,OutputStream fout)
              {
                  boolean flag=true;
                  try {
                      Connection conn = DataSourceUtils.getConnection(getJdbcTemplate().getDataSource());
                      conn.setAutoCommit(false);                        //此部分ms能提高性能
                      Statement st = conn.createStatement();
                      ResultSet rs = st.executeQuery(sql);
                      if (rs.next()) {
                          java.sql.Blob blob = rs.getBlob(1);
                          InputStream ins = blob.getBinaryStream();
                          //輸出到文件
                          //下面將BLOB數(shù)據(jù)寫入文件
                          byte[] b = new byte[1024];
                          int len = 0;
                          while ((len = ins.read(b)) != -1) {
                              fout.write(b, 0, len);
                          }
                          //依次關(guān)閉
                          fout.close();
                          ins.close();
                      }
                      conn.commit();
                      rs.close();             //maybe not nessesary
                      st.close();             //maybe not nessesary
                      conn.close();
                  } catch (IOException ex) {
                      flag=false;
                  } catch (SQLException ex) {
                      flag=false;
                  }
                  return flag;
              }
          2.如果把blob對象放到記錄的字段中,在web開發(fā)中,通過blob.getBinaryStream()只能獲得一次blob流,第二次調(diào)用同一對象的blob流會得到null流。
          且在這種方式下,不能使用in.close()關(guān)閉流。

          posted on 2012-07-17 15:34 chen11-1 閱讀(17860) 評論(0)  編輯  收藏 所屬分類: oracle

          主站蜘蛛池模板: 渝中区| 乌鲁木齐县| 衡水市| 都江堰市| 长治市| 清原| 岳阳市| 浪卡子县| 凤凰县| 华宁县| 孝义市| 大姚县| 绥中县| 宝丰县| 防城港市| 萨迦县| 镇安县| 正安县| 沙湾县| 浪卡子县| 城口县| 田阳县| 南阳市| 雷州市| 长丰县| 青浦区| 敦煌市| 汕尾市| 土默特右旗| 如皋市| 呼图壁县| 上林县| 延边| 卫辉市| 西畴县| 固安县| 潢川县| 株洲县| 安西县| 凉山| 鄂托克旗|