- 浏览: 21175 次
- 性别:
文章分类
最新评论
-
geeksun:
pstmt.setString(1,content); ...
用jsp上传图片文件,存贮到字段类型为blob的流形式代码 -
snakeaiyu:
程序有问题!
用jsp上传图片文件,存贮到字段类型为blob的流形式代码 -
zidane0207:
引用[url][/url]
操作Oracle数据库实现上传图片到Blob类型的字段出现的问题
1.JSP/html页面里面读取web服务器上的图片,也就是把图片放到(上传)到web 服务器上,然后用html 语句读取:<o:p></o:p>
绝对或相对路径 " border="0" /><o:p></o:p>
2.就是上传到数据库里面(oracle).关于oracle 数据库,它支持blob, 和clob, 分别对应着图片和文本(长字符串)操作<o:p></o:p>
由于性能原因,我们还是要采用第二种方法,而且存到数据库里面比较容易管理,是吧?<o:p></o:p>
<o:p> </o:p>
首先,我们要解决上传问题,这里采用普遍使用的apache commons 组件里面的FileUpload class.<o:p></o:p>
具体步骤如:<o:p></o:p>
<o:p> </o:p>
DiskFileUpload dfu=new DiskFileUpload();<o:p></o:p>
dfu.setSizeMax(100000000);<o:p></o:p>
dfu.setSizeThreshold(100000);<o:p></o:p>
dfu.setRepositoryPath("f:\\public");<o:p></o:p>
<o:p></o:p>
try{<o:p></o:p>
List fileItems=dfu.parseRequest(request);<o:p></o:p>
Iterator i=fileItems.iterator();<o:p></o:p>
<o:p></o:p>
while(i.hasNext()){<o:p></o:p>
FileItem fi=(FileItem)i.next();<o:p></o:p>
if(!fi.isFormField()){<o:p></o:p>
name=fi.getName(); <o:p></o:p>
size=fi.getSize(); <o:p></o:p>
if((name==null||name.equals(""))&&size==0)<o:p></o:p>
continue;<o:p></o:p>
}<o:p></o:p>
name=fi.getName();<o:p></o:p>
size=fi.getSize();<o:p></o:p>
(InputStream)is=fi.getInputStream();<o:p></o:p>
<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
上面的代码是web服务器接受上传的代码,参考文件已经在我上篇写的上传文本文件里给出,今天,终于想明白了:<o:p></o:p>
dfu.setRepositoryPath("f:\\public"); 的意思<o:p></o:p>
原来是转义字符也就是说\n\t等而要打印反斜杠要用\\,其实这个问题原先已经知道,可是由于经验没有写过图片上传处理什么的,觉得很高深,也很可怕,哈哈,心里有点畏惧.看来基础的东西,那怕一点点小细节也很重要,接着还有下面的java IO 问题.刚才读core java 的时候突然发现在讲io的时候特意提醒了这个问题,可是我没有注意!<o:p></o:p>
<o:p> </o:p>
通过上面的代码已经实现文件上传了.然后,我们要实现JDBC数据源链接,目的是要把数据插入到oracle.<o:p></o:p>
<o:p></o:p>
Context ctx=new InitialContext();<o:p></o:p>
DataSource ds=(DataSource)ctx.lookup("jdbc/asdbCoreDS");<o:p></o:p>
conn=ds.getConnection();<o:p></o:p>
conn.setAutoCommit(false);<o:p></o:p>
关于要import java.sql.* javax.sql.* java.naming.* 不再详细叙述了<o:p></o:p>
接着根据很有用的一篇文章的提示,插入blob类型一定要先1.插入一个空的<o:p></o:p>
String insert=" insert into uploadpicture "+<o:p></o:p>
" values(?, empty_blob()) " ;<o:p></o:p>
2.然后找到这个blob的oracle 里面的游标:<o:p></o:p>
String findCursor=" select content "+<o:p></o:p>
" from uploadpicture "+<o:p></o:p>
" where name=? for update ";<o:p></o:p>
注意这个for update(注意!!!必须加for update,这将锁定该行,直至该行被修改完毕,保证不产生并发冲突。这里还是难以理解,先记下来吧)<o:p></o:p>
3.然后再修改<o:p></o:p>
String update=" update uploadpicture "+<o:p></o:p>
" set content=? "+<o:p></o:p>
" where name=? ";<o:p></o:p>
这里的问号是为PreparedStatement参数处理而写的!<o:p></o:p>
<o:p> </o:p>
写这个程序用到了oracle.sql.BLOB class ,这个类是用来操作BLOB数据类型的<o:p></o:p>
当我们通过ResultSet 对象得到<o:p></o:p>
blob=(BLOB)rs.getBlob(1);<o:p></o:p>
的时候我不知道如何处理了,Blob 是什么?String, int ,long? 我现在也不明白!估计CSDN上的人也不明白,否则我发个帖子半天,也许是很烂,也许是太简单了,大家不屑一顾,看来我还要继续追赶!<o:p></o:p>
不发牢骚了,回到程序里(总觉得自己的发散思维很强,看来写程序的时候不能这样,多亏java 是纯面向对象语言,如果是过程就麻烦了)<o:p></o:p>
我们如何处理这个blob 呢?回答是,不管它是什么,直接写入 BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());<o:p></o:p>
这里是建立了缓冲写如blob 的流(注意getBinaryOutputStream()已经不被赞成使用了,一定有更优秀的方法替代!),说到流,我到现在还有点晕,类很多,不知道究竟用哪个好!<o:p></o:p>
基础的东西非常重要,这曾经是我的口头禅,这里用到了流的读入写和写入,有些流是从文件或其它位置上读取字节(如, FileInputStream),有写流是把字节组合成有用的数据(如, DataInputStream).我们读取数字的时候,需要首先建议一个FileInpuStream, 然后, 再把该类的对象传递给DataInputStream<o:p></o:p>
FileInputStream fin=new FileInputStream(“emp.dat”);<o:p></o:p>
DataInputStream din=new DataInputStream(fin);//把fin传递给din<o:p></o:p>
double s=din.readDouble();<o:p></o:p>
默认情况下,流是没有缓冲的, 如果使用缓冲就是<o:p></o:p>
DataInputStream din=new DataInputStream(<o:p></o:p>
new BufferedInputStream(new FileINputStream(“emp.dat”)));<o:p></o:p>
<o:p> </o:p>
有了这点理解也很管用,<o:p></o:p>
BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());<o:p></o:p>
就是建立一个缓冲写的对象到blob.注意这里的out1 不是out,否则程序运行的时候不能打印了temp 数据了!<o:p></o:p>
已经准备好如何写了, 可是如何读呢?<o:p></o:p>
BufferedInputStream in=new BufferedInputStream(is);<o:p></o:p>
在我们上传的时候 (InputStream)is=fi.getInputStream();<o:p></o:p>
读取图片为输入的流.保存为is 对象,然后就用到这里了,准备好了读和写了,我们开始干活:<o:p></o:p>
int c;<o:p></o:p>
while((c=in.read())!=-1) {out1.write(c);}<o:p></o:p>
in.close();<o:p></o:p>
out1.close();<o:p></o:p>
通过缓冲一个个读数据,然后一个个写数据.-1 为文件的末尾,<o:p></o:p>
最后当读写完成后我们要关闭读写对象!<o:p></o:p>
程序分析就是这样,以后还要对此问题进行研究,最后还要注意,<o:p></o:p>
<%@ page contentType="image/jpeg;charset=GBK"%><o:p></o:p>
不是<o:p></o:p>
<%@ page contentType="text/html;charset=GBK"%><o:p></o:p>
否则是以文字显示图片---乱码.<o:p></o:p>
<o:p> </o:p>
这里研究了上传图片到oralce 里面的程序,关于显示还要麻烦一点,借助资料我实现了,明天再研究一下.<o:p></o:p>
<o:p>
</o:p>
<o:p> //插入上传图片到数据库
<%@ 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">
getPicture.jsp
</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!"+"
");
//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!"+"
");
out.println("cursor :"+blob+"
");
//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!"+"
");}
conn.commit();
}
catch(SQLException se)
{se.printStackTrace();}
catch(FileUploadException fue)
{fue.printStackTrace();}
%>
</body></o:p>
<o:p></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.*"%></o:p>
<html>
<head>
<meta http-equiv="Content-Type" content="image/jpeg; charset=GBK">
showDBImage.jsp
</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+"
");*/}
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>
发表评论
-
[转]软件架构师成长之路
2007-12-28 12:02 260CSDN Blog推出文章指数概 ... -
在Oracle中用HibernateJDBC对图片数据的操作(更新)
2007-10-18 23:00 1257关于如何使用JDBC来操控oracle的blob数据类型: ... -
操作Oracle数据库实现上传图片到Blob类型的字段出现的问题
2007-10-12 00:42 1887通过使用OleDb操作Oracle数据库,成功实现图片上传到B ... -
用jsp上传图片文件,存贮到字段类型为blob的流形式代码
2007-10-12 00:37 3329向Mssql数据库写入image代码的程序,所以我在这在写一下 ... -
【转】用jsp上传图片文件,存贮到字段类型为blob的流形式代码
2007-10-12 00:34 2119向Mssql数据库写入image代码的程序,所以我在这在写一下 ... -
【转】JDBC,Hibernate将Blob型数据到Oracle中
2007-10-12 00:32 1120...
相关推荐
Oracle数据库系统支持这两种数据类型,用于存储大量文本数据和二进制数据。下面将详细介绍这两种数据类型以及如何在Oracle中使用它们存储和读取图片。 1. **CLOB数据类型**: `CLOB`数据类型用于存储大量的字符...
MyBatis 提供了对 CLOB 和 BLOB 类型的内置支持,通过将 CLOB 类型映射到 Java 的 String 类型,BLOB 类型映射到 byte[] 类型。 在使用 MyBatis 时,需要在实体类中定义对应的字段类型,例如: ```java public ...
在Oracle数据库中,`BLOB`(Binary Large Object)和`CLOB`(Character Large Object)是用于存储大量数据的两种特殊数据类型。这两种类型都属于`LOB`(Large Object)类别,主要用于处理大数据量的存储问题。 ####...
此外,Clob类型通常用于存储文本数据,例如文章内容,与图片存储无关,但其处理方式与Blob类似,只是涉及到字符流而不是二进制流。在本例中,我们主要讨论了Blob类型,因为它是存储图像数据的关键。
Oracle数据库是世界上最广泛使用的数据库系统之一,特别是在企业级应用中。在Oracle8i版本中,数据库支持了大型对象(LOB)类型,包括BLOB(Binary Large Object)和CLOB(Character Large Object)。这两种数据类型...
在Oracle数据库中,插入和查询BLOB和CLOB对象有特定的方法: 1. 插入操作: - BLOB插入:可以使用DBMS_LOB包中的函数,如DBMS_LOB.CREATETEMPORARY和DBMS_LOB.WRITE来创建并填充BLOB对象。然后,将这个对象作为...
Oracle数据库中的BLOB(Binary Large Object)字段是用来存储大量二进制数据的,例如图片、文档或音频文件。在Delphi编程环境中,处理这类数据时需要掌握特定的API调用和方法。本篇文章将深入探讨如何在Delphi中对...
总结来说,Oracle数据库中的CLOB和BLOB类型是处理大量文本和二进制数据的关键。在JDBC中,我们可以通过`PreparedStatement`进行高效且安全的插入、更新和查询操作。理解如何正确地使用这些数据类型和相关的JDBC方法...
Oracle数据库系统支持对大型数据对象(LOBs,Large Objects)的操作,这包括BLOB、CLOB、NCLOB和BFILE四种类型。每种类型都有其特定的用途和特性,适用于存储不同类型的大数据。 1. BLOB(Binary Large Object): ...
这两种类型都是用于存储大量数据,BLOB用于二进制数据,如图片、音频或视频文件,而CLOB则用于存储大量的文本数据,如XML文档或长篇文本。 在Oracle中,Blob和Clob的处理涉及到许多关键知识点,包括创建、读取、...
Blob通常用于存储二进制数据,如图片、音频或视频文件,而Clob则用于存储大量文本数据,如长篇的文本或XML文档。在JDBC4中,处理LOB对象变得更为直接和高效,主要归功于新增的`java.sql.Blob`和`java.sql.Clob`接口...
CLOB类型用于存储大量的文本数据,而BLOB则适用于二进制大数据,如图片或视频。当插入或更新包含大字段的数据时,ORACLE会采用不同的策略以优化存储和性能。 1. **LOB存储模式**: - **临时LOB**:数据存放在内存...
这些数据类型通常用于存储大量的文本数据(Clob)和二进制数据(Blob),例如长篇文章、图片或音频文件。在Oracle数据库中,Hibernate提供了与这些数据类型的交互方式。本篇将详细介绍在Hibernate中如何处理Clob和...
在Oracle数据库中,有多种数据类型用于存储不同类型的数据,其中包括Long、Raw和Blob。这些字段类型各有其特性和用途,下面我们将详细探讨它们,并通过一个简单的示例来展示如何在Oracle数据库中对这些类型进行读写...
在Oracle数据库中,BLOB(Binary Large Object)和CLOB(Character Large Object)是两种用于存储大量数据的特殊字段类型。本篇文章将深入剖析如何使用MyBatis框架在Oracle数据库中对BLOB类型字段进行保存和读取。 ...
在Oracle数据库中,有多种数据类型用于存储不同类型的数据,其中包括Long、Raw和Blob。这些字段类型各有其特性和用途。 1. Long类型:Long数据类型用于存储大文本数据,如用户简历(EMP_DESCLONG)。它能存储的最大...
BLOB用于存储二进制数据,如图片和音频文件,而CLOB用于存储字符数据,如文本文件。NCLOB与CLOB类似,但用于存储特定字符集的大量字符数据。BFILE则用于存储操作系统级别的文件,提供对大型外部文件的引用。 在...
在Java的持久化框架Hibernate中,处理大数据类型如Oracle数据库中的Clob(Character Large Object)和Blob(Binary Large Object)字段是一项重要的任务。Clob通常用于存储大量的文本数据,而Blob则适用于二进制...
- 在Oracle数据库中处理`CLOB`字段时,需要特别注意。首先,需要插入一个空值,然后通过查询锁定该行,再更新`CLOB`字段。这是因为Oracle的`CLOB`需要先创建空间,然后再写入数据。 - 插入示例: ```java conn....
5. 配置数据库:创建相应的表,包含存储图片路径或元数据的字段,可能需要使用 BLOB 或 CLOB 类型来存储大文件。 6. 显示图片:在需要显示图片的页面,根据数据库中存储的路径加载图片。 注意,文件上传时要确保...