分享
 
 
 

插入图片/文本(blob /clob)到oracle数据库

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

reference: http://www.weste.net/2004/11-3/12250047377.html

我们在写OA的时候经常遇到的问题就是员工图片档案的储存问题,解决这个问题有两个方法,

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>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有