插入圖片/文字(blob /clob)到oracle資料庫
OA的時候經常遇到的問題就是員工圖片檔案的儲存問題,解決這個問題有兩個方法,<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
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>
</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>