大龙的博客

常用链接

统计

最新评论

oracle blob数据存取

    Oracle中的lob (Large Object)可以存储非常大的数据(可能是4GB),这样就可以通过将文件或其它任何对象序列化成字节输出流(OutputStream)后写入数据 库,之后使用字节输入流(InputStream)将数据读出然后反序列化为原始文件或对象。操作时需要使用oracle的JDBC包,它扩展了sun的 JDBC包中的Blob对象。
    以下是一个保存图片进数据库的例子:
1.servlet:用于保存图片并将图片输出
Java代码  收藏代码
  1. package com.logcd.servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.OutputStream;  
  6. import java.sql.CallableStatement;  
  7. import java.sql.Connection;  
  8. import java.sql.DriverManager;  
  9. import java.sql.ResultSet;  
  10. import java.sql.SQLException;  
  11. import java.sql.Statement;  
  12. import java.sql.Types;  
  13. import java.util.Iterator;  
  14. import java.util.List;  
  15.   
  16. import javax.servlet.ServletException;  
  17. import javax.servlet.http.HttpServlet;  
  18. import javax.servlet.http.HttpServletRequest;  
  19. import javax.servlet.http.HttpServletResponse;  
  20.   
  21. import oracle.sql.BLOB;  
  22.   
  23. import org.apache.commons.fileupload.FileItem;  
  24. import org.apache.commons.fileupload.FileUploadException;  
  25. import org.apache.commons.fileupload.disk.DiskFileItemFactory;  
  26. import org.apache.commons.fileupload.servlet.ServletFileUpload;  
  27.   
  28. public class ImageServlet extends HttpServlet {  
  29.   
  30.     private static final long serialVersionUID = 1L;  
  31.   
  32.     /** 
  33.      * 处理请求 
  34.      * @throws FileUploadException 
  35.      */  
  36.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  37.             throws ServletException, IOException {  
  38.   
  39.         Iterator<FileItem> i = getFileItem(request);  
  40.         String title = "";  
  41.         byte[] data = null;  
  42.   
  43.         while (i.hasNext()) {  
  44.             FileItem fi = (FileItem) i.next();  
  45.             if (fi.isFormField()) {// 取得表单域  
  46.                 if(fi.getFieldName().equalsIgnoreCase("title")){  
  47.                               title = new String(fi.getString().getBytes("iso8859-1"),"gbk");  
  48.                     }  
  49.             } else {// 取文件域  
  50.                 data = fi.get();//文件二进制数据  
  51.             }  
  52.         }  
  53.   
  54.         Integer id = saveImageUseProc(data,title);//saveImage(data, title);//存入   
  55.         //outputImage(response, id);//读出  
  56.         outputImageUseProc(response,id);  
  57.     }  
  58.   
  59.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  60.             throws ServletException, IOException {  
  61.         doPost(request, response);  
  62.     }  
  63.   
  64.     /** 
  65.      * 通过SQL保存图片 
  66.      * @param data 
  67.      * @param title 
  68.      */  
  69.     @SuppressWarnings("deprecation")  
  70.     public static Integer saveImage(byte[] data, String title) {  
  71.         Connection conn = getConnection();  
  72.         Integer id = (int) (Math.random() * 100000);  
  73.         String sql = "insert into t_image(id,title,image) values(" + id + ",'"  
  74.                 + title + "',empty_blob())";  
  75.         Statement stmt;  
  76.         OutputStream outStream = null;  
  77.         try {  
  78.             conn.setAutoCommit(false);// 如果不关闭会报-->"错误:读取违反顺序"  
  79.   
  80.             stmt = conn.createStatement();  
  81.             stmt.execute(sql);  
  82.   
  83.             String sqll = "select image from t_image where id=" + id  
  84.                     + " for update";  
  85.   
  86.             ResultSet rs = stmt.executeQuery(sqll);  
  87.             if (rs.next()) {  
  88.                 BLOB blob = (BLOB) rs.getBlob("image");  
  89.                 outStream = blob.getBinaryOutputStream();  
  90.                 // data是传入的byte数组,定义:byte[] data  
  91.                 outStream.write(data, 0, data.length);  
  92.   
  93.                 outStream.flush();  
  94.                 outStream.close();  
  95.                 conn.commit();  
  96.             }  
  97.         } catch (Exception e) {  
  98.             try {  
  99.                 conn.rollback();  
  100.             } catch (SQLException e1) {  
  101.                 e1.printStackTrace();  
  102.             }  
  103.             e.printStackTrace();  
  104.         } finally {  
  105.             try {  
  106.                 conn.close();  
  107.             } catch (SQLException e) {  
  108.                 e.printStackTrace();  
  109.             }  
  110.         }  
  111.         return id;  
  112.   
  113.     }  
  114.   
  115.     /** 
  116.      * 调用存储过程保存图片 
  117.      * @param data 
  118.      * @param title 
  119.      * @return 
  120.      */  
  121.     @SuppressWarnings("deprecation")  
  122.     public static Integer saveImageUseProc(byte[] data, String title){  
  123.         Integer id = null;  
  124.         BLOB blob = null;  
  125.         OutputStream outStream;  
  126.         Connection conn = getConnection();  
  127.         try{  
  128.             conn.setAutoCommit(false);  
  129.             String call="{call OPERATE_BLOB.SAVE_BLOB_IMAGE(?,?,?)}";//调用语句  
  130.             CallableStatement proc=conn.prepareCall(call);//调用存储过程  
  131.             proc.setString(1, title);  
  132.             proc.registerOutParameter(2, Types.BLOB);  
  133.             proc.registerOutParameter(3, Types.INTEGER);   
  134.               
  135.             proc.execute();  
  136.               
  137.             blob = (BLOB)proc.getBlob(2);  
  138.             id = proc.getInt(3);//返回结果  
  139.   
  140.             outStream = blob.getBinaryOutputStream();  
  141.             outStream.write(data, 0, data.length);  
  142.             outStream.flush();  
  143.             outStream.close();  
  144.               
  145.             proc.close();  
  146.             conn.commit();  
  147.         }catch(Exception e){  
  148.             e.printStackTrace();  
  149.         }finally{  
  150.             try {  
  151.                 conn.close();  
  152.             } catch (SQLException e) {  
  153.                 e.printStackTrace();  
  154.             }  
  155.         }  
  156.           
  157.         return id;  
  158.     }  
  159.   
  160.     /** 
  161.      * 输出保存的图片 
  162.      * @param response 
  163.      * @param id 
  164.      */  
  165.     public static void outputImage(HttpServletResponse response, Integer id) {  
  166.         Connection con = getConnection();  
  167.         byte[] data = null;  
  168.         try{  
  169.             Statement st = con.createStatement();  
  170.             ResultSet rs = st.executeQuery("select image from t_image where id="  
  171.                     + id);  
  172.             if (rs.next()) {  
  173.                 BLOB blob = (BLOB)rs.getBlob("image");  
  174.                 InputStream inStream = blob.getBinaryStream();  
  175.                 int bufferSize = blob.getBufferSize();  
  176.                 data = new byte[bufferSize];  
  177.                 int count = inStream.read(data, 0, bufferSize);  
  178.                 while(count != -1){//读出字节数据  
  179.                     response.getOutputStream().write(data,0,count);  
  180.                     count = inStream.read(data, 0, bufferSize);  
  181.                 }  
  182.                 inStream.close();  
  183.             }  
  184.         }catch(Exception e){  
  185.             e.printStackTrace();  
  186.         }finally{  
  187.             try {  
  188.                 con.close();  
  189.             } catch (SQLException e) {  
  190.                 e.printStackTrace();  
  191.             }  
  192.   
  193.         }  
  194.     }  
  195.   
  196.     /** 
  197.      * 调用存储过程输出图片 
  198.      * @param response 
  199.      * @param id 
  200.      */  
  201.     public static void outputImageUseProc(HttpServletResponse response, Integer id){  
  202.         Connection conn = getConnection();  
  203.         try{  
  204.             String call = "{call OPERATE_BLOB.QUERY_BLOB_IMAGE(?,?)}";  
  205.             CallableStatement proc=conn.prepareCall(call);//调用存储过程  
  206.               
  207.             proc.setInt(1, id);  
  208.             proc.registerOutParameter(2, Types.BLOB);  
  209.               
  210.             proc.execute();  
  211.               
  212.             BLOB blob = (BLOB)proc.getBlob(2);  
  213.               
  214.             InputStream inStream = blob.getBinaryStream();  
  215.             int bufferSize = blob.getBufferSize();  
  216.             byte[] data = new byte[bufferSize];  
  217.             int count = inStream.read(data, 0, bufferSize);  
  218.             while(count != -1){//读出字节数据  
  219.                 response.getOutputStream().write(data,0,count);  
  220.                 count = inStream.read(data, 0, bufferSize);  
  221.             }  
  222.             inStream.close();  
  223.               
  224.         }catch(Exception e){  
  225.             e.printStackTrace();  
  226.         }finally{  
  227.             try {  
  228.                 conn.close();  
  229.             } catch (SQLException e) {  
  230.                 e.printStackTrace();  
  231.             }  
  232.         }  
  233.     }  
  234.       
  235.     /** 
  236.      * 取得所有表单数据 
  237.      * @param request 
  238.      * @return 
  239.      */  
  240.     @SuppressWarnings("unchecked")  
  241.     public static Iterator<FileItem> getFileItem(HttpServletRequest request) {  
  242.         DiskFileItemFactory factory = new DiskFileItemFactory();  
  243.         factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb  
  244.         ServletFileUpload upload = new ServletFileUpload(factory);  
  245.         upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB  
  246.   
  247.         List<FileItem> items = null;  
  248.         Iterator<FileItem> i = null;  
  249.         try {  
  250.             items = upload.parseRequest(request);  
  251.             i = items.iterator();  
  252.         } catch (FileUploadException e) {  
  253.             e.printStackTrace();  
  254.         }  
  255.   
  256.         return i;  
  257.     }  
  258.   
  259.     /** 
  260.      * 取得数据库连接 
  261.      *  
  262.      * @return 
  263.      */  
  264.     public static Connection getConnection() {  
  265.         String driver = "oracle.jdbc.driver.OracleDriver";  
  266.         String url = "jdbc:oracle:thin:@195.2.199.6:1521:orcl";  
  267.         Connection conn = null;  
  268.         try {  
  269.             Class.forName(driver);  
  270.             conn = DriverManager.getConnection(url, "testdb", "logcd");  
  271.         } catch (ClassNotFoundException e) {  
  272.             e.printStackTrace();  
  273.         } catch (SQLException ex) {  
  274.             ex.printStackTrace();  
  275.         }  
  276.         return conn;  
  277.     }  
  278.   
  279. }  

2.所用到的存储过程
Sql代码  收藏代码
  1. CREATE OR REPLACE PACKAGE BODY OPERATE_BLOB AS  
  2.   
  3.   PROCEDURE  SAVE_BLOB_IMAGE(  
  4.       PC_TITLE  IN   VARCHAR2,  
  5.       PB_IMAGE  OUT   BLOB,  
  6.       PN_ID     OUT  INTEGER  
  7.     )AS  
  8.       v_id INTEGER;  
  9.   BEGIN     
  10.        SELECT nvl(MAX(id),1000) + 1 INTO v_id FROM t_image;   
  11.        PN_ID := v_id;  
  12.        INSERT INTO t_image(id,title,image) values(v_id,PC_TITLE,empty_blob())  
  13.        RETURNING image INTO PB_IMAGE;  
  14.   
  15.   END;  
  16.   
  17.   PROCEDURE QUERY_BLOB_IMAGE(  
  18.      PN_ID      IN   INTEGER,  
  19.      PB_IMAGE   OUT  BLOB  
  20.   )AS  
  21.   BEGIN  
  22.      SELECT image INTO PB_IMAGE FROM t_image WHERE id = PN_ID;    
  23.   END;  
  24.   
  25. END;  


3.web.xml配置servlet
Xml代码  收藏代码
  1. <servlet>  
  2.     <servlet-name>ImageServlet</servlet-name>  
  3.     <servlet-class>com.logcd.servlet.ImageServlet</servlet-class>  
  4. </servlet>  
  5. <servlet-mapping>  
  6.     <servlet-name>ImageServlet</servlet-name>  
  7.     <url-pattern>/imageServlet</url-pattern>  
  8. </servlet-mapping>  

4.在image.html页面中调用下
Html代码  收藏代码
  1. <HTML>  
  2.     <HEAD>  
  3.         <TITLE>Image File</TITLE>  
  4.         <meta http-equiv="Content-Type" content="text/html; charset=gb2312">  
  5.     </HEAD>  
  6.     <FORM method="POST" encType="multipart/form-data" action="imageServlet">  
  7.         <INPUT type="text" name="title">  
  8.         <BR>  
  9.         <INPUT type="file" name="image">  
  10.         <BR>  
  11.         <INPUT type="submit" value="提交">  
  12.     </FORM>  
  13.     <BODY>  
  14.     </BODY>  
  15. </HTML> 

posted on 2012-06-19 17:42 大龙 阅读(642) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理