国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

在Oracle中存取BLOB對象實現文件的上傳和下載

2024-08-29 13:33:04
字體:
來源:轉載
供稿:網友

  最近做一個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這個空對象。代碼如下:
  
  //得到數據庫連接(驅動包是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();
  
  //插入一個空對象
  
  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">
  
  </form>
  
  (2)由于JSP沒有提供文件上傳的處理能力,只有使用第三方的開發包。網絡上開源的包有很多,我們這里選擇Apache Jakarta的FileUpload,在http://jakarta.apache.org/commons/fileupload/index.Html 可以得到下載包和完整的API文檔。法奧為adajspException
  
  處理頁面(handle.jsp)的代碼如下
  
  <%
  
  boolean isMultipart = FileUpload.isMultipartContent(request);
  
  if (isMultipart) {
  
  // 建立一個新的Upload對象
  
  DiskFileUpload upload = new DiskFileUpload();
  
  // 設置上載文件的參數
  
  //upload.setSizeThreshold(yourMaxMemorySize);
  
  //upload.setSizeMax(yourMaxRequestSize);
  
  String rootPath = getServletConfig().getServletContext().getRealPath("/") ;
  
  upload.setRepositoryPath(rootPath+"http://uploads");
  
  // 分析request中的傳來的文件流,返回Item的集合,
  
  // 輪詢Items,假如不是表單域,就是一個文件對象。
  
  List items = upload.parseRequest(request);
  
  Iterator iter = items.iterator();
  
  while (iter.hasNext()) {
  
  FileItem item = (FileItem) iter.next();
  
  //假如是文件對象
  
  if (!item.isFormField()) {
  
  //假如是文本文件,可以直接顯示
  
  //out.println(item.getString());
  
  //將上載的文件寫到服務器的/WEB-INF/webstart/下,文件名為test.txt
  
  //File uploadedFile = new File(rootPath+"http://uploads//test.txt");
  
  //item.write(uploadedFile);
  
  //下面的代碼是將文件入庫(略):
  
  //注重輸入流的獲取
  
  …
  
  InputStream uploadedStream = item.getInputStream();
  
  …
  
  }
  
  //否則是普通表單
  
  else{
  
  out.println("FieldName: " + item.getFieldName()+"<br>");
  
  out.println("Value: "+item.getString()+"<br>");    }
  
  }
  
  }
  
  %>
  
  4.從數據庫讀取BLOB然后保存到客戶端磁盤上
  這段代碼有點詭異,執行后將會彈出文件保存對話窗口,將BLOB數據讀出保存到本地


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大竹县| 福建省| 霍林郭勒市| 沂水县| 新乡县| 辉县市| 天气| 南宫市| 津市市| 平罗县| 广河县| 余干县| 东乡县| 洛浦县| 绥德县| 定西市| 山东省| 南靖县| 景谷| 湘乡市| 马公市| 伊金霍洛旗| 谢通门县| 吴忠市| 许昌县| 陈巴尔虎旗| 绵竹市| 舒城县| 兖州市| 汪清县| 龙井市| 南丹县| 乳山市| 游戏| 昌江| 阿荣旗| 宁陵县| 双城市| 云龙县| 沙雅县| 双峰县|