需要編寫程序,將圖片以二進(jìn)制流的方式讀取并插入到數(shù)據(jù)庫數(shù)據(jù)表中。數(shù)據(jù)庫中對應(yīng)字段類型可設(shè)置為BLOB
10年的十堰網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。成都營銷網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整十堰建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“十堰網(wǎng)站設(shè)計”,“十堰網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
在開發(fā)過程中,經(jīng)常會遇到oracle中存圖片的情況,下面就為您想介紹一個可以輕松在oracle中存圖片的方法,希望對您能有所幫助。
一個存儲圖片文件的過程,任何開發(fā)工具都可以通過調(diào)用過程把圖片文存儲到數(shù)據(jù)庫中。
oracle中存圖片的詳細(xì)步驟:
SQL connect chanet/chanet@oradb;
已連接。
SQL CREATE TABLE IMAGE_LOB (T_ID VARCHAR2 (5) NOT NULL,T_IMAGE BLOB NOT NULL);
表已創(chuàng)建。
SQL CREATE OR REPLACE DIRECTORY IMAGES AS 'C:\Oracle'; --圖片目錄
目錄已創(chuàng)建。
SQL CREATE OR REPLACE PROCEDURE IMG_INSERT (TID VARCHAR2,FILENAME VARCHAR2) AS F_LOB BFILE; B_LOB BLOB; BEGIN INSERT INTO IMAGE_LOB (T_ID, T_IMAGE) VALUES (TID,EMPTY_BLOB ()) RETURN T_IMAGE INTO B_LOB; F_LOB:= BFILENAME ('IMAGES', FILENAME); DBMS_LOB.FILEOPEN (F_LOB, DBMS_LOB.FILE_READONLY); DBMS_LOB.LOADFROMFILE (B_LOB, F_LOB, DBMS_LOB.GETLENGTH (F_LOB)); DBMS_LOB.FILECLOSE (F_LOB); COMMIT; END; /
過程已創(chuàng)建。
SQL EXEC IMG_INSERT('1','f_TEST.jpg');
PL/SQL 過程已成功完成。
create table test
(
NID VARCHAR2(1) not null,
IMG BLOB,
zhengqueFlag VARCHAR2(1),
cuowuFlag VARCHAR2(1)
)
說明:
1、IMG字段只需要保存圖片,將圖片信息經(jīng)過Base64編碼,存到數(shù)據(jù)庫BLOB字段中。顯示的時候要經(jīng)過Base64解碼。
2、對于像“正確”、“錯誤”用標(biāo)志位在區(qū)別。你可以用1表示正確、0表示錯誤。當(dāng)然你也可以用漢字的保存這樣的信息。自己來設(shè)計。
然后你到網(wǎng)上查一下怎么樣對BLOB字段進(jìn)行操作。如果不行,我在增加回復(fù)。
var MsImg: TMemoryStream;
begin
MsImg := TMemoryStream.Create;
MsImg.LoadFromFile(errorimage);
TmpQuery.close;
TmpQuery.sql.text:='select * from 數(shù)據(jù)表名 where 條件';
TmpQuery.open;
TmpQuery.edit;
TBlobField(TmpQuery.fieldbyname('字段名')).LoadFromStream(MsImg);
TmpQuery.post;
end;
system下執(zhí)行
create?or?replace?directory?BlobFile?as?'C:\TEMP';--路徑自己改一下
grant?read?on?directory?BlobFile?to?scott;
scott下建立存放的表
Create?Table?blobTest(
filename?varchar2(200),
filedesc?varchar2(200),
filebody?blob);
創(chuàng)建過程
Create?Or?Replace?Procedure?Proc_loadBlob(p_filename?varchar2,p_filedesc?varchar2)
Is
src_file?bfile;
dst_file?BLOB;
lgh_file?binary_integer;
Begin
src_file?:=?bfilename('BLOBFILE',p_filename);
insert?into?blobTest(filename,filedesc,filebody)
values?(p_filename,p_filedesc,EMPTY_BLOB())
returning?filebody?into?dst_file;
dbms_lob.fileopen(src_file,dbms_lob.file_readonly);
lgh_file?:=?dbms_lob.getlength(src_file);
dbms_lob.loadfromfile(dst_file,src_file,lgh_file);
update?blobTest
set?filebody?=?dst_file
where?filename?=?p_filename;
dbms_lob.fileclose(src_file);
End?Proc_loadBlob;
執(zhí)行插入:
exec?Proc_loadBlob('101101.jpeg','給圖片命名);
你要是非弄個id的話,可以自己建立一個序列,到時候自增就好了呀
最后給你上圖
插入圖片/文本(blob /clob)到oracle數(shù)據(jù)庫(引用)
我們在寫OA的時候經(jīng)常遇到的問題就是員工圖片檔案的儲存問題,解決這個問題有兩個方法,
1.JSP/html頁面里面讀取web服務(wù)器上的圖片,也就是把圖片放到(上傳)到web 服務(wù)器上,然后用html 語句讀?。?/p>
img src=" 絕對或相對路徑 " border="0" /
2.就是上傳到數(shù)據(jù)庫里面(oracle).關(guān)于oracle 數(shù)據(jù)庫,它支持blob, 和clob, 分別對應(yīng)著圖片和文本(長字符串)操作
由于性能原因,我們還是要采用第二種方法,而且存到數(shù)據(jù)庫里面比較容易管理,是吧?
首先,我們要解決上傳問題,這里采用普遍使用的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服務(wù)器接受上傳的代碼,參考文件已經(jīng)在我上篇寫的上傳文本文件里給出,今天,終于想明白了:
dfu.setRepositoryPath("f:\\public"); 的意思
原來是轉(zhuǎn)義字符也就是說\n\t等而要打印反斜杠要用\\,其實這個問題原先已經(jīng)知道,可是由于經(jīng)驗沒有寫過圖片上傳處理什么的,覺得很高深,也很可怕,哈哈,心里有點(diǎn)畏懼.看來基礎(chǔ)的東西,那怕一點(diǎn)點(diǎn)小細(xì)節(jié)也很重要,接著還有下面的java IO 問題.剛才讀core java 的時候突然發(fā)現(xiàn)在講io的時候特意提醒了這個問題,可是我沒有注意!
通過上面的代碼已經(jīng)實現(xiàn)文件上傳了.然后,我們要實現(xiàn)JDBC數(shù)據(jù)源鏈接,目的是要把數(shù)據(jù)插入到oracle.
Context ctx=new InitialContext();
DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");
conn=ds.getConnection();
conn.setAutoCommit(false);
關(guān)于要import java.sql.* javax.sql.* java.naming.* 不再詳細(xì)敘述了
接著根據(jù)很有用的一篇文章的提示,插入blob類型一定要先1.插入一個空的
String insert=" insert into uploadpicture "+
" values(?, empty_blob()) " ;
2.然后找到這個blob的oracle 里面的游標(biāo):
String findCursor=" select content "+
" from uploadpicture "+
" where name=? for update ";
注意這個for update(注意?。?!必須加for update,這將鎖定該行,直至該行被修改完畢,保證不產(chǎn)生并發(fā)沖突。這里還是難以理解,先記下來吧)
3.然后再修改
String update=" update uploadpicture "+
" set content=? "+
" where name=? ";
這里的問號是為PreparedStatement參數(shù)處理而寫的!
寫這個程序用到了oracle.sql.BLOB class ,這個類是用來操作BLOB數(shù)據(jù)類型的
當(dāng)我們通過ResultSet 對象得到
blob=(BLOB)rs.getBlob(1);
的時候我不知道如何處理了,Blob 是什么?String, int ,long? 我現(xiàn)在也不明白!估計CSDN上的人也不明白,否則我發(fā)個帖子半天沒有人回答,也許是很爛,也許是太簡單了,大家不屑一顧,看來我還要繼續(xù)追趕!
不發(fā)牢騷了,回到程序里(總覺得自己的發(fā)散思維很強(qiáng),看來寫程序的時候不能這樣,多虧java 是純面向?qū)ο笳Z言,如果是過程就麻煩了)
我們?nèi)绾翁幚磉@個blob 呢?回答是,不管它是什么,直接寫入 BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());
這里是建立了緩沖寫如blob 的流(注意getBinaryOutputStream()已經(jīng)不被贊成使用了,一定有更優(yōu)秀的方法替代!),說到流,我到現(xiàn)在還有點(diǎn)暈,類很多,不知道究竟用哪個好!
基礎(chǔ)的東西非常重要,這曾經(jīng)是我的口頭禪,這里用到了流的讀入寫和寫入,有些流是從文件或其它位置上讀取字節(jié)(如, FileInputStream),有寫流是把字節(jié)組合成有用的數(shù)據(jù)(如, DataInputStream).我們讀取數(shù)字的時候,需要首先建議一個FileInpuStream, 然后, 再把該類的對象傳遞給DataInputStream
FileInputStream fin=new FileInputStream(“emp.dat”);
DataInputStream din=new DataInputStream(fin);//把fin傳遞給din
double s=din.readDouble();
默認(rèn)情況下,流是沒有緩沖的, 如果使用緩沖就是
DataInputStream din=new DataInputStream(
new BufferedInputStream(new FileINputStream(“emp.dat”)));
有了這點(diǎn)理解也很管用,
BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());
就是建立一個緩沖寫的對象到blob.注意這里的out1 不是out,否則程序運(yùn)行的時候不能打印了temp 數(shù)據(jù)了!
已經(jīng)準(zhǔn)備好如何寫了, 可是如何讀呢?
BufferedInputStream in=new BufferedInputStream(is);
在我們上傳的時候 (InputStream)is=fi.getInputStream();
讀取圖片為輸入的流.保存為is 對象,然后就用到這里了,準(zhǔn)備好了讀和寫了,我們開始干活:
int c;
while((c=in.read())!=-1) {out1.write(c);}
in.close();
out1.close();
通過緩沖一個個讀數(shù)據(jù),然后一個個寫數(shù)據(jù).-1 為文件的末尾,
最后當(dāng)讀寫完成后我們要關(guān)閉讀寫對象!
程序分析就是這樣,以后還要對此問題進(jìn)行研究,最后還要注意,
%@ page contentType="image/jpeg;charset=GBK"%
不是
%@ page contentType="text/html;charset=GBK"%
否則是以文字顯示圖片---亂碼.
這里研究了上傳圖片到oralce 里面的程序,關(guān)于顯示還要麻煩一點(diǎn),借助資料我實現(xiàn)了,明天再研究一下.
//插入上傳圖片到數(shù)據(jù)庫
%@ 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"
titlegetPicture.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(a0)
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
//顯示數(shù)據(jù)庫里面的圖片
%@ 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"
titleshowDBImage.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