插入圖片/文本(blob /clob)到oracle數據庫(引用http://www.java-asp.net/java/200512/t_48888.html)
Posted on 2006-07-21 16:41 Kevin Meng 閱讀(1227) 評論(0) 編輯 收藏1.JSP/html頁面里面讀取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.然后找到這個blob的oracle 里面的游標:
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>
//顯示數據庫里面的圖片
<%@ 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>