1. 程式人生 > >插入圖片/文字(blob /clob)到oracle資料庫

插入圖片/文字(blob /clob)到oracle資料庫

OA的時候經常遇到的問題就是員工圖片檔案的儲存問題,解決這個問題有兩個方法,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1.JSPhtml頁面裡面讀取web伺服器上的圖片,也就是把圖片放到(上傳)到web 伺服器上,然後用html 語句讀取:

<img src=" 絕對或相對路徑 " border="0" />

2.就是上傳到資料庫裡面(oracle).關於oracle 資料庫,它支援blob, clob, 分別對應著圖片和文字(長字串)操作

由於效能原因,我們還是要採用第二種方法

,而且存到資料庫裡面比較容易管理,是吧?

首先,我們要解決上傳問題,這裡採用普遍使用的apache commons 元件裡面的FileUpload class.

具體步驟如:

DiskFileUpload dfu=new DiskFileUpload();

dfu.setSizeMax(100000000);

dfu.setSizeThreshold(100000);

dfu.setRepositoryPath("f://public");

try{

List fileItems=dfu.parseRequest(request);

Iterator i=fileItems.iterator();

while(i.hasNext()){

FileItem fi=(FileItem)i.next();

if(!fi.isFormField()){

name=fi.getName();

size=fi.getSize();

if((name==null||name.equals(""))&&size==0)

continue;

}

name=fi.getName();

size=fi.getSize();

(InputStream)is=fi.getInputStream();

}

上面的程式碼是web伺服器接受上傳的程式碼,參考檔案已經在我上篇寫的上傳文字檔案裡給出,今天,終於想明白了:

dfu.setRepositoryPath("f://public");

的意思

原來是轉義字元也就是說/n/t等而要列印反斜槓要用//,其實這個問題原先已經知道,可是由於經驗沒有寫過圖片上傳處理什麼的,覺得很高深,也很可怕,哈哈,心裡有點畏懼.看來基礎的東西,那怕一點點小細節也很重要,接著還有下面的java IO 問題.剛才讀core java 的時候突然發現在講io的時候特意提醒了這個問題,可是我沒有注意!

通過上面的程式碼已經實現檔案上傳了.然後,我們要實現JDBC資料來源連結,目的是要把資料插入到oracle.

Context ctx=new InitialContext();

DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");

conn=ds.getConnection();

conn.setAutoCommit(false);

關於要import java.sql.* javax.sql.* java.naming.* 不再詳細敘述了

接著根據很有用的一篇文章的提示,插入blob型別一定要先1.插入一個空的

String insert=" insert into uploadpicture "+

" values(?, empty_blob()) ";

2.然後找到這個bloboracle 裡面的遊標:

String findCursor=" select content "+

" from uploadpicture "+

" where name=?for update ";

注意這個for update(注意!!!必須加for update,這將鎖定該行,直至該行被修改完畢,保證不產生併發衝突。這裡還是難以理解,先記下來吧)

3.然後再修改

String update=" update uploadpicture"+

" set content=? "+

" where name=? ";

這裡的問號是為PreparedStatement引數處理而寫的!

寫這個程式用到了oracle.sql.BLOB class ,這個類是用來操作BLOB資料型別的

當我們通過ResultSet 物件得到

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

的時候我不知道如何處理了,Blob 是什麼?String, int ,long? 我現在也不明白!估計CSDN上的人也不明白,否則我發個帖子半天沒有人回答,也許是很爛,也許是太簡單了,大家不屑一顧,看來我還要繼續追趕!

不發牢騷了,回到程式裡(總覺得自己的發散思維很強,看來寫程式的時候不能這樣,多虧java 是純面嚮物件語言,如果是過程就麻煩了)

我們如何處理這個blob ?回答是,不管它是什麼,直接寫入BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());

這裡是建立了緩衝寫如blob 的流(注意getBinaryOutputStream()已經不被贊成使用了,一定有更優秀的方法替代!),說到流,我到現在還有點暈,類很多,不知道究竟用哪個好!

基礎的東西非常重要,這曾經是我的口頭禪,這裡用到了流的讀入寫和寫入,有些流是從檔案或其它位置上讀取位元組(, FileInputStream),有寫流是把位元組組合成有用的資料(, DataInputStream).我們讀取數字的時候,需要首先建議一個FileInpuStream, 然後, 再把該類的物件傳遞給DataInputStream

FileInputStream fin=new FileInputStream(“emp.dat”);

DataInputStream din=new DataInputStream(fin);//fin傳遞給din

double s=din.readDouble();

預設情況下,流是沒有緩衝的, 如果使用緩衝就是

DataInputStream din=new DataInputStream(

new BufferedInputStream(new FileINputStream(“emp.dat”)));

有了這點理解也很管用,

BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());

就是建立一個緩衝寫的物件到blob.注意這裡的out1 不是out,否則程式執行的時候不能列印了temp 資料了!

已經準備好如何寫了, 可是如何讀呢?

BufferedInputStream in=new BufferedInputStream(is);

在我們上傳的時候(InputStream)is=fi.getInputStream();

讀取圖片為輸入的流.儲存為is 物件,然後就用到這裡了,準備好了讀和寫了,我們開始幹活:

int c;

while((c=in.read())!=-1) {out1.write(c);}

in.close();

out1.close();

通過緩衝一個個讀資料,然後一個個寫資料.-1 為檔案的末尾,

最後當讀寫完成後我們要關閉讀寫物件!

程式分析就是這樣,以後還要對此問題進行研究,最後還要注意,

<%@ page contentType="image/jpeg;charset=GBK"%>

不是

<%@ page contentType="text/html;charset=GBK"%>

否則是以文字顯示圖片---亂碼.

這裡研究了上傳圖片到oralce 裡面的程式,關於顯示還要麻煩一點,藉助資料我實現了,明天再研究一下.

 //插入上傳圖片到資料庫
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%@ page import="org.apache.commons.*"%>
<%@ page import="org.apache.commons.fileupload.*"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="oracle.sql.*"%>
<html>
 
 
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK">
    <title>getPicture.jsp</title>
  </head>
 
 
 
 
  <body>
 
  <%
  request.setCharacterEncoding("GBK");
   
 
  String name=null;
  long size=0;
 
  Connection conn=null;
  String insert=" insert into uploadpicture "+
                " values(?, empty_blob()) "     ;
 
  String findCursor=" select content "+
                    " from uploadpicture "+
                    " where name=?  for update ";
 
  String update=" update uploadpicture  "+
                " set content=? "+
                " where name=? ";
  BLOB blob=null;
    InputStream is=null;
 
  DiskFileUpload dfu=new DiskFileUpload();
  dfu.setSizeMax(100000000);
  dfu.setSizeThreshold(100000);
  dfu.setRepositoryPath("f://public");
 
  try{
  List fileItems=dfu.parseRequest(request);
  Iterator i=fileItems.iterator();
 
  while(i.hasNext()){
  FileItem fi=(FileItem)i.next();
  if(!fi.isFormField()){
  name=fi.getName();                   
  size=fi.getSize();                    
  if((name==null||name.equals(""))&&size==0)
  continue;
                        }
  name=fi.getName();
  size=fi.getSize();
  is=fi.getInputStream();
 
                    }
                   
  Context ctx=new InitialContext();
  DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");
  conn=ds.getConnection();
  conn.setAutoCommit(false);
 
  //step 1
  PreparedStatement ps=conn.prepareStatement(insert);
  ps.setString(1, name);
  int a=ps.executeUpdate();
  if(a>0)
  out.println("insert success!"+"<br>");
 
  //step 2
  ps=conn.prepareStatement(findCursor);
  ps.setString(1, name); 
  ResultSet rs=ps.executeQuery();
  while(rs.next())
  {
  blob=(BLOB)rs.getBlob(1);
 
 
   out.println("find cursor success!"+"<br>");
   out.println("cursor            :"+blob+"<br>");
  //step 3
  ps=conn.prepareStatement(update);
  ps.setBlob(1, blob);
  ps.setString(2, name);
  ps.executeUpdate();
  ps.close();
  BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());
  BufferedInputStream in=new BufferedInputStream(is);
  int c;
  while((c=in.read())!=-1) {out1.write(c);}
  in.close();
  out1.close();
  out.println("update success!"+"<br>");}
  conn.commit();
  }
 
  catch(SQLException se)
  {se.printStackTrace();}
  catch(FileUploadException fue)
  {fue.printStackTrace();}
  %>
 
 
  </body>

</html>


//顯示資料庫裡面的圖片

<%@ page contentType="image/jpeg;charset=GBK"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>
<%@ page import="java.io.*"%>
<%@ page import="com.sun.image.codec.jpeg.*"%>
<%@ page import="javax.imageio.*"%>
<%@ page import="java.util.*"%>
<%@ page import="java.awt.image.*"%>


<html>
 
 
 
  <head>
    <meta http-equiv="Content-Type" content="image/jpeg; charset=GBK">
    <title>showDBImage.jsp</title>
  </head>
 
 
 
  <body>
  <%
  String showImage=" select * "+
                   " from uploadpicture "+
                   " where name='TXC with snow.JPG' " ;
  Connection conn=null;
  BufferedInputStream inputImage=null;
 
 
  try{
  Context ctx=new InitialContext();
  DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");
  conn=ds.getConnection();
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(showImage);
  while(rs.next())
  {
  oracle.sql.BLOB blob=(oracle.sql.BLOB)rs.getBlob("content");
  inputImage =new BufferedInputStream(blob.getBinaryStream());
  /*String name=rs.getString(1);
  String content=rs.getString(2);
  out.println(name+"<br>");*/}
 
  BufferedImage image=null;
  image=ImageIO.read(inputImage);
 
  ServletOutputStream sos=response.getOutputStream();
  JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(sos);
  encoder.encode(image);
  inputImage.close();
  conn.commit();
 
  }
  catch(SQLException se)
  {se.printStackTrace();
  conn.rollback();  }
  catch(IOException ie)
  {ie.printStackTrace();} 
  %>
 
  </body>


</html>