(100分新手求教)把图片保存到Oracle的BLOB字段中的问题

小安安 2007-06-12 09:52:03
现在有一数据库(Oracle)如下
表 Person
ID Name Picture
1 aaaaa (blob)
请问如何用jsp写添加一条记录,编辑一条记录,显示一条记录.
主要是图片的Blob字段.如何添加,编辑,显示.
请高手帮忙
...全文
1251 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaray 2007-10-02
  • 打赏
  • 举报
回复
将图片保存到数据库中客户端用<img src="/aImgReadServlet?pictureId=<%=pictureId%>"></img>

在aImgReadServlet 中
1. 获得pictureId,再用这个pictureId查询blob字段,获得其输出流;
2. 再获得response输出流;
3. 将图片blob的输出流写到response输出流;
4. 执行收尾工作:关闭数据库资源,关闭response输出流,等等。
Makaveli 2007-10-02
  • 打赏
  • 举报
回复
学习了
laogou 2007-09-30
  • 打赏
  • 举报
回复
UP
Cappuccino_mhc 2007-07-02
  • 打赏
  • 举报
回复
1楼的太猛了

整不了了

看的就行
小安安 2007-07-02
  • 打赏
  • 举报
回复
来人啊
Forestjsp 2007-07-02
  • 打赏
  • 举报
回复
你可以更改一下,具体有什么不懂可以加我QQ..19085498
Forestjsp 2007-07-02
  • 打赏
  • 举报
回复
强烈推荐更改数据库字段! 存路径吧!
曾经.
我和楼主一样,也是设计了一个 blob字段 .可以实现存储.但是到后来读取图片的时候就不知道怎么吧图片放到合适的地方.

后来我发现用存路径的方法方便实用得多!!
先用jspsmartupload包.将图片存到服务器上,再改名字.这样就避免了重名.
然后将路径存到数据库中.

我把代码给你吧.
<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*,com.jspsmart.upload.*,java.text.SimpleDateFormat" errorPage="" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>文件上传</title>
</head>
<jsp:useBean id="db" scope="page" class="duban.DataBean"/>
<jsp:useBean id="tb" scope="page" class="duban.ToolBean"/>
<body>
<%
String icode=(String)session.getAttribute("code");
String iname=(String)session.getAttribute("name");

if(icode==null || iname==null)
{
out.println("<script language=\"javascript\">window.parent.location.href=\"nologin.jsp\";</script>");
return;
}

String fzrcode=(String)session.getAttribute("fzrcode");

%>

<%
String root=getServletContext().getRealPath("/");
root=root+"image\\qianming\\";

String src="";
try{
SmartUpload su = new SmartUpload();
su.initialize(pageContext);
//su.setMaxFileSize(10000);
//su.setAllowedFilesList("jpg,gif,bmp,dib,jpeg");
//su.setAllowedFilesList("doc,txt");
su.upload();
//int count = su.save("C:/Tomcat/webapps/duban/image/qianming",su.SAVE_PHYSICAL);
com.jspsmart.upload.File file = su.getFiles().getFile(0);
String strExt = su.getFiles().getFile(0).getFileExt();
java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyyMMddHHmmssSSS");//取系统时间,精确到毫秒。
java.util.Date date = new java.util.Date();
String strTime = simpleDateFormat.format(date);
String strFileName = strTime + "." + strExt;
//String FilePath = "C:/Tomcat/webapps/duban/image/qianming"+strFileName;//uploadpath为保存目录名。

//判断服务器使用的操作系统,处理文件的存放目录
if(root.indexOf("\\",0)>= 0){//windown
root=root.substring(root.lastIndexOf("/")+1);

src="..\\image\\qianming\\"+strFileName;
}else{//linux
root=root.substring(root.lastIndexOf("\\")+1);
src="../image/qianming/"+strFileName;
}
file.saveAs(root+strFileName,su.SAVE_PHYSICAL);


}
catch(Exception e){
out.println("<script language=javascript>alert(\"请确认图片大小和类型是否合适\");</script>");
}
%>


<%

Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String sql="";

try{
conn=db.GetConnection();
conn.setAutoCommit(false);
stmt=conn.createStatement();
sql="update db_fuzeren set qianming='"+src+"' where code='"+fzrcode+"'";
stmt.execute(sql);
conn.commit();
response.sendRedirect("fuzeren_index.jsp");
}
catch(Exception e){
conn.rollback();
out.println("<div align=center>添加负责人失败!"+sql+"</div>");
out.println(e);
out.println("<p><p><div align=center><a href=javascript:history.back();>返回前页</a></div>");
}
finally{
if(rs!=null) rs.close();
if(stmt!=null) stmt.close();
if(conn!=null && !conn.isClosed()) conn.close();
}
%>
</body>
</html>
zhbking 2007-07-02
  • 打赏
  • 举报
回复
存路径不是更好,省得那么麻烦,实现也容易得多.何必庸人自扰呢?
denghan 2007-07-02
  • 打赏
  • 举报
回复
建议存大文本使用blob,存图片使用clob
------------------------------------
应该是:

建议存大文本使用clob,存图片使用blob
BKscofild 2007-07-02
  • 打赏
  • 举报
回复
MARK
小安安 2007-06-14
  • 打赏
  • 举报
回复
高手帮忙啊, 快来啊
jyh149129 2007-06-12
  • 打赏
  • 举报
回复
10g+ojdbc14驱动,保存时,jndi也是没有问题的
indeed 2007-06-12
  • 打赏
  • 举报
回复
二楼说的不错,路过,学习
南南北北 2007-06-12
  • 打赏
  • 举报
回复
学习之。
Stone_G 2007-06-12
  • 打赏
  • 举报
回复
我是新手,有些措辞可能不太专业~
首先,如果你是用jndi获取连接的话,驱动支持不支持blob操作
因为,我就遇到过,根本没有实现blob操作,害我查了半天
一、增加
1、先用 insert into person (name,picture) values ('picname',empty_blob())
2、再 select * from person where name='picname' for update
oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("picture"); // 得到BLOB对象
File file = new File("C:\\......");// 得到file对象
if(file.exists()&&file.isFile()){//如果文件存在,并且文件为file
OutputStream out = blob.getBinaryOutputStream(); // 建立输出流
InputStream in = new FileInputStream(file); // 建立输入流
int size = blob.getBufferSize();
byte[] buffer = new byte[size]; // 建立缓冲区
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
in.close();
out.close();
}
file.delete();
二、修改
和新增里面的方法一样
三、查看
看二楼的方法,因为查看的方法很多,不知道你要哪种? 下载?预览?
ycoolb 2007-06-12
  • 打赏
  • 举报
回复
要转成2进制
jdbc中如何处理Oracle BLOB字段

为什么我要写这篇文章?

在前段时间我所在的项目中,就碰到了这个问题,我花了2天的时间才将BLOB的问题搞定。我也尝试过网上所介绍的各种方法,那些方法所

使用的原理都一致,但都写得不完整,我也按照网上介绍的方法做了,但都因为其中一些没有提到的小的细节而失败。希望看到这篇文章的人

都不再走弯路。

一般人会走哪些弯路?
1.使用jdk中的方法进行传输。在ResultSet 中有getBlob()方法,在PreparedStatement中有setBlob()方法,所以大多数人都会尝试setBlob

(),getBlob() 进行读写,或者两个数据库之间BLOB的传输。这种方法实际上是行不通的,据网上的一些资料介绍,说sun官方的文档有些方法

都是错误的。
2.使用ResultSet.getBinaryStream 和PreparedStatement.setBinaryStream对BLOB进行读写或两个数据库间的传输。这种方法我自己尝试过,

发现,如果BLOB中存储的是文本文件的话,就没问题,如果是二进制文件,传输就会有问题。

根据自己的经验,以及查阅了Oracle的官方文档,都是使用如下处理方法:
1.新建记录,插入BLOB数据
1.1首先新建记录的时候,使用oracle的函数插入一个空的BLOB,假设字段A是BLOB类型的:
insert xxxtable(A,B,C) values(empty_blob(),'xxx','yyyy')
1.2后面再查询刚才插入的记录,然后更新BLOB,在查询前,注意设置Connection的一个属性:
conn.setAutoCommit(false);如果缺少这一步,可能导致fetch out of sequence等异常.
1.3 查询刚才插入的记录,后面要加“ for update ”,如下:
select A from xxxtable where xxx=999 for update ,如果缺少for update,可能出现row containing the LOB value is not locked

的异常
1.4 从查询到的 BLOB字段中,获取blob并进行更新,代码如下:
BLOB blob = (BLOB) rs.getBlob("A");
OutputStream os = blob.getBinaryOutputStream();
BufferedOutputStream output = new BufferedOutputStream(os);

后面再使用output.write方法将需要写入的内容写到output中就可以了。例如我们将一个文件写入这个字段中:
BufferedInputStream input = new BufferedInputStream(new File("c:\\hpWave.log").toURL().openStream());
byte[] buff = new byte[2048]; //用做文件写入的缓冲
int bytesRead;
while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
output.write(buff, 0, bytesRead);
System.out.println(bytesRead);
}
上面的代码就是从input里2k地读取,然后写入到output中。
1.5上面执行完毕后,记得关闭output,input,以及关闭查询到的ResultSet
1.6最后执行conn.commit();将更新的内容提交,以及执行conn.setAutoCommit(true); 改回Connction的属性
2.修改记录,方法与上面的方法类似,
2.1首先更新BLOB以外的其他字段
2.2 使用1.3中类似的方法获取记录
2.3 修改的过程中,注意以下:a 需要更新的记录中,BLOB有可能为NULL,这样在执行blob.getBinaryOutputStream()获取的值可能为

null,那么就关闭刚才select的记录,再执行一次update xxxtable set A = empty_blob() where xxx, 这样就先写入了一个空的BLOB(不是null),然后再

使用1.3,1.4中的方法执行更新记录.b 注意别忘了先执行setAutoCommit(false),以及"for update",以及后面的conn.commit();等。
3.读取BLOB字段中的数据.
3.1 读取记录不需要setAutoCommit(),以及 select ....for update.
3.2 使用普通的select 方法查询出记录
3.3 从ResultSet中获取BLOB并读取,如下:
BLOB b_to = (BLOB) rs.getBlob("A");
InputStream is = b_from.getBinaryStream();
BufferedInputStream input = new BufferedInputStream(is);
byte[] buff = new byte[2048];
while(-1 != (bytesRead = input.read(buff, 0, buff.length))) {
//在这里执行写入,如写入到文件的BufferedOutputStream里
System.out.println(bytesRead);
}
通过循环取出blob中的数据,写到buff里,再将buff的内容写入到需要的地方
4.两个数据库间blob字段的传输
类似上面1和3的方法,一边获取BufferedOutputStream,另外一边获取BufferedInputStream,然后读出写入,需要注意的是写入所用的

Connection要执行conn.setAutoCommit(false);以及获取记录时添加“ for update ”以及最后的commit();

总结以上方法,其根本就是先创建空的BLOB,再获取其BufferedOutputStream进行写入,或获取BufferedInputStream进行读取
africa 2007-06-12
  • 打赏
  • 举报
回复
建议存大文本使用blob,存图片使用clob
小安安 2007-06-12
  • 打赏
  • 举报
回复
比方如页面中有一个地方是blob中的图片的如:<img src=""></img>请问要怎么弄才能把数据库中的Blob字段的图片显示在网页上啊

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧