在Oracle中存取BLOB對象實現檔案的上傳和下載____Oracle

來源:互聯網
上載者:User

最近做一個J2EE項目,需要在JSP頁面實現對檔案的上傳和下載。很早以前就知道JDBC支援大對象(LOB)的存取,以為很容易,做起來才發現問題多多,讀了一大堆文章,反而沒有什麼頭緒了。正如一位網友文章所講:“…網路上的教程99%都是行不通的,連SUN自己的文檔都一直錯誤……”,實際情況大致如此了。

 

 

 

存取BLOB出現這麼多問題,我認為大半是由資料庫開發商、應用伺服器商在JDBC驅動上的不相容性帶來的。而實際應用中,每個人的開發運行環境不同,使得某個網友的solution沒有辦法在別人的應用中重現,以至於罵聲一片。至於為什麼會不相容、有哪些問題,我沒有時間去弄清,這裡只說說我們怎樣解決了問題的。

 

 

 

基於上述原因,先列出我們的開發環境,免得有人配不出來,招人唾罵。

資料庫 Oracle 9i

應用伺服器 BEA Weblogic 8.11

開發工具 JBuilder X

 

 

 

在JSP實現檔案Upload/Download可以分成這樣幾塊 :檔案提交到形成InputSteam;InputSteam以BLOB格式入庫;資料從庫中讀出為InputSteam;InputStream輸出到頁面形成下載檔案。先說BLOB吧。

 

 

 

1.  BLOB入庫

(1)       直接獲得資料庫連接的情況

這是Oracle提供的標準方式,先插入一個空BLOB對象,然後Update這個Null 物件。代碼如下:

//得到資料庫連接(驅動包是weblogic的,沒有下載任何新版本)

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection con = DriverManager.getConnection(

          "jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");

//處理事務

con.setAutoCommit(false);

Statement st = con.createStatement();

//插入一個Null 物件

st.executeUpdate("insert into BLOBIMG  values(103,empty_blob())");

//用for update方式鎖定資料行

ResultSet rs = st.executeQuery(

          "select contents from  BLOBIMG  where  id=103 for update");

if (rs.next()) {

   //得到java.sql.Blob對象,然後Cast為oracle.sql.BLOB

oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob(1).;

   //到資料庫的輸出資料流

OutputStream outStream = blob.getBinaryOutputStream();

   //這裡用一個檔案類比輸入資料流

File file = new File("d://proxy.txt");

  InputStream fin = new FileInputStream(file);

//將輸入資料流寫到輸出資料流

byte[] b = new byte[blob.getBufferSize()];

        int len = 0;

        while ( (len = fin.read(b)) != -1) {

          outStream.write(b, 0, len);

          //blob.putBytes(1,b);

        }

 

 

 

   //依次關閉(注意順序)

fin.close();

   outStream.flush();

   outStream.close();

   con.commit();

   con.close();

 

 

 

(2)       通過JNDI獲得資料庫連接

在Weblogic中配置到Oracle的JDBC Connection Pool和DataSource,綁定到Context中,假定綁定名為”orads”。

為了得到資料庫連接,做一個串連工廠,主要代碼如下:

Context context = new InitialContext();

ds = (DataSource) context.lookup("orads");

return ds.getConnection();

以下是BLOB寫入資料庫的代碼:

 

 

 

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

st.executeUpdate("insert into BLOBIMG values(103,empty_blob())");

ResultSet rs = st.executeQuery(

          "select contents from  BLOBIMG  where  id=103 for update");

if (rs.next()) {

    //上面代碼不變

//這裡不能用oracle.sql.BLOB,會報ClassCast 異常

weblogic.jdbc.vendor.oracle.OracleThinBlobblob = (weblogic.jdbc.vendor.oracle.OracleThinBlob) rs.getBlob(1);

    //以後代碼也不變

OutputStream outStream = blob.getBinaryOutputStream();

File file = new File("d://proxy.txt");

  InputStream fin = new FileInputStream(file);

byte[] b = new byte[blob.getBufferSize()];

        int len = 0;

        while ( (len = fin.read(b)) != -1) {

          outStream.write(b, 0, len);

        }

 

 

 

fin.close();

   outStream.flush();

   outStream.close();

   con.commit();

   con.close();

 

 

 

2.  BLOB出庫

從資料庫中讀出BLOB資料沒有上述由於串連池的不同帶來的差異,只需要J2SE的標準類java.sql.Blob就可以取得輸出資料流(注意區別java.sql.Blob和oracle.sql.BLOB)。代碼如下:

Connection con = ConnectionFactory.getConnection();

con.setAutoCommit(false);

Statement st = con.createStatement();

//這裡的SQL語句不再需要”for update”

ResultSet rs = st.executeQuery(

          "select contents from  BLOBIMG  where  id=103 ");

if (rs.next()) {

   java.sql.Blob blob = rs.getBlob(1);

 

 

 

   InputStream ins = blob.getBinaryStream();

 

 

 

    //用檔案類比輸出資料流

File file = new File("d://output.txt");

   OutputStream fout = new FileOutputStream(file);

 

 

 

    //下面將BLOB資料寫入檔案

    byte[] b = new byte[1024];

    int len = 0;

        while ( (len = ins.read(b)) != -1) {

          fout.write(b, 0, len);

        }

  //依次關閉

  fout.close();

  ins.close();

  con.commit();

  con.close();

 

 

 

3.  從JSP頁面提交檔案到資料庫

 

 

 

(1)       提交頁面的代碼如下:

<form action="handle.jsp" enctype="multipart/form-data" method="post" >

<input type="hidden" name="id" value="103"/>

<input type="file"  name="fileToUpload">

<input type="submit"  value="Upload">

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.