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. }  
package com.logcd.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import oracle.sql.BLOB;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class ImageServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	/**
	 * 处理请求
	 * @throws FileUploadException
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		Iterator<FileItem> i = getFileItem(request);
		String title = "";
		byte[] data = null;

		while (i.hasNext()) {
			FileItem fi = (FileItem) i.next();
			if (fi.isFormField()) {// 取得表单域
				if(fi.getFieldName().equalsIgnoreCase("title")){
                              title = new String(fi.getString().getBytes("iso8859-1"),"gbk");
					}
			} else {// 取文件域
				data = fi.get();//文件二进制数据
			}
		}

		Integer id = saveImageUseProc(data,title);//saveImage(data, title);//存入 
		//outputImage(response, id);//读出
		outputImageUseProc(response,id);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * 通过SQL保存图片
	 * @param data
	 * @param title
	 */
	@SuppressWarnings("deprecation")
	public static Integer saveImage(byte[] data, String title) {
		Connection conn = getConnection();
		Integer id = (int) (Math.random() * 100000);
		String sql = "insert into t_image(id,title,image) values(" + id + ",'"
				+ title + "',empty_blob())";
		Statement stmt;
		OutputStream outStream = null;
		try {
			conn.setAutoCommit(false);// 如果不关闭会报-->"错误:读取违反顺序"

			stmt = conn.createStatement();
			stmt.execute(sql);

			String sqll = "select image from t_image where id=" + id
					+ " for update";

			ResultSet rs = stmt.executeQuery(sqll);
			if (rs.next()) {
				BLOB blob = (BLOB) rs.getBlob("image");
				outStream = blob.getBinaryOutputStream();
				// data是传入的byte数组,定义:byte[] data
				outStream.write(data, 0, data.length);

				outStream.flush();
				outStream.close();
				conn.commit();
			}
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return id;

	}

	/**
	 * 调用存储过程保存图片
	 * @param data
	 * @param title
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static Integer saveImageUseProc(byte[] data, String title){
		Integer id = null;
		BLOB blob = null;
		OutputStream outStream;
		Connection conn = getConnection();
		try{
			conn.setAutoCommit(false);
			String call="{call OPERATE_BLOB.SAVE_BLOB_IMAGE(?,?,?)}";//调用语句
		    CallableStatement proc=conn.prepareCall(call);//调用存储过程
            proc.setString(1, title);
            proc.registerOutParameter(2, Types.BLOB);
		    proc.registerOutParameter(3, Types.INTEGER); 
            
            proc.execute();
            
            blob = (BLOB)proc.getBlob(2);
            id = proc.getInt(3);//返回结果

			outStream = blob.getBinaryOutputStream();
			outStream.write(data, 0, data.length);
			outStream.flush();
			outStream.close();
            
			proc.close();
            conn.commit();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return id;
	}

	/**
	 * 输出保存的图片
	 * @param response
	 * @param id
	 */
	public static void outputImage(HttpServletResponse response, Integer id) {
		Connection con = getConnection();
		byte[] data = null;
		try{
			Statement st = con.createStatement();
			ResultSet rs = st.executeQuery("select image from t_image where id="
					+ id);
			if (rs.next()) {
				BLOB blob = (BLOB)rs.getBlob("image");
				InputStream inStream = blob.getBinaryStream();
				int bufferSize = blob.getBufferSize();
				data = new byte[bufferSize];
				int count = inStream.read(data, 0, bufferSize);
				while(count != -1){//读出字节数据
					response.getOutputStream().write(data,0,count);
					count = inStream.read(data, 0, bufferSize);
				}
				inStream.close();
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 调用存储过程输出图片
	 * @param response
	 * @param id
	 */
	public static void outputImageUseProc(HttpServletResponse response, Integer id){
		Connection conn = getConnection();
        try{
        	String call = "{call OPERATE_BLOB.QUERY_BLOB_IMAGE(?,?)}";
		    CallableStatement proc=conn.prepareCall(call);//调用存储过程
            
		    proc.setInt(1, id);
		    proc.registerOutParameter(2, Types.BLOB);
		    
		    proc.execute();
		    
		    BLOB blob = (BLOB)proc.getBlob(2);
			
		    InputStream inStream = blob.getBinaryStream();
			int bufferSize = blob.getBufferSize();
			byte[] data = new byte[bufferSize];
			int count = inStream.read(data, 0, bufferSize);
			while(count != -1){//读出字节数据
				response.getOutputStream().write(data,0,count);
				count = inStream.read(data, 0, bufferSize);
			}
			inStream.close();
		    
        }catch(Exception e){
        	e.printStackTrace();
        }finally{
        	try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
        }
	}
	
	/**
	 * 取得所有表单数据
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Iterator<FileItem> getFileItem(HttpServletRequest request) {
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB

		List<FileItem> items = null;
		Iterator<FileItem> i = null;
		try {
			items = upload.parseRequest(request);
			i = items.iterator();
		} catch (FileUploadException e) {
			e.printStackTrace();
		}

		return i;
	}

	/**
	 * 取得数据库连接
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@195.2.199.6:1521:orcl";
		Connection conn = null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, "testdb", "logcd");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException ex) {
			ex.printStackTrace();
		}
		return conn;
	}

}


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;  
CREATE OR REPLACE PACKAGE BODY OPERATE_BLOB AS

  PROCEDURE  SAVE_BLOB_IMAGE(
      PC_TITLE  IN   VARCHAR2,
      PB_IMAGE  OUT   BLOB,
      PN_ID     OUT  INTEGER
    )AS
      v_id INTEGER;
  BEGIN   
       SELECT nvl(MAX(id),1000) + 1 INTO v_id FROM t_image; 
       PN_ID := v_id;
       INSERT INTO t_image(id,title,image) values(v_id,PC_TITLE,empty_blob())
       RETURNING image INTO PB_IMAGE;

  END;

  PROCEDURE QUERY_BLOB_IMAGE(
     PN_ID      IN   INTEGER,
     PB_IMAGE   OUT  BLOB
  )AS
  BEGIN
     SELECT image INTO PB_IMAGE FROM t_image WHERE id = PN_ID;  
  END;

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>  
    <servlet>
        <servlet-name>ImageServlet</servlet-name>
        <servlet-class>com.logcd.servlet.ImageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ImageServlet</servlet-name>
        <url-pattern>/imageServlet</url-pattern>
    </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>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值