主题:使用JAVA读取ORACLE BLOB字段实现上传下载
作者:蔡毅(caiyi0903@hotmail.com)
时间:2005-6-22
一 BLOB概述
大对象类型BLOB全称为Binary Large Objects,即二进制大对象。可以把BLOB区别为三种形式:声像数据、二进制数据和大文本数据。因此,最常见的应用就是存储图形、声音等对象,此外大二进制对象、OLE对象也可以通过BLOB类型存入数据库,如果文本对象过大,超出了文本类型的规定长度,则必须用BLOB字段进行存储。我们在经常使用的编程环境中并不能直接支持BLOB字段,因此需要调用相应的函数完成BLOB的使用。
二 实际Struts项目的处理流程
1 插入BLOB字段的流程
表示层:
上传使用struts的<html:file property="drawingFile"/>标签,提交给指定处理的Action,在ActionForm中使用struts自带的FormFile
来保存文件。
核心代码:
<html:form action="/DrawingInputMultiAction" enctype="multipart/form-data">
<html:file property="drawingFile"/>
....省略
</html:form>
控制层:
在Action中将传入的ActionForm中的文件字段赋给VO值对象,并调用业务代理类的上传方法。
核心代码:
//新增
if(actionType.equals("insert")) {
//得到文件类型
int iFileType = this.getFileType(drawingInputForm.getFileExtendName());
if(iFileType == 0) {
//不支持文件类型
this.addError(request, "drawing.errors.upload.UnSupportedFileType");
} else {
DrawingVO objDrawingVO = new DrawingVO();
//图纸基本属性
objDrawingVO.setDrawingName(drawingInputForm.getDrawingName());
...省略其他set方法
//执行新增(上传)
int iRt = objDrawingMan.insertDrawing(objDrawingVO);
...省略
}
Facade门面:
通过业务代理类调用DAO中的上传方法,对客户端完全透明。
public int insertDrawing(DrawingVO drawingVO) throws ComtopModuleException {
try {
DrawingDAO drawingDAO = new DrawingDAO();
return drawingDAO.insertDrawing(drawingVO);
} catch(DrawingException ex) {
throw new ComtopModuleException("drawing.errors.insert", ex);
}
}
持久层:
DAO中实现和ORACLE数据库的底层交涉,完成真正的文件上传。
需要先插入一个空BLOB对象,然后Update这个空对象。
public int insertDrawing(DrawingVO drawingVO) throws DrawingException {
PreparedStatement pstmt = null;
Statement stmt = null;
Connection conn = null;
int iKey = 0;
ResultSet rs = null;
//定义SQL语句
String strSQLInsert = null;
String strSQLUpdate = null;
try {
conn = dataSource.getConnection();
conn.setAutoCommit(false);
//插入空BLOB,empty_blob(),其中表中的Content是BLOC类型字段
strSQLInsert =
"insert into PROD_DRAWING (DRAWING_ID, DRAWING_NAME, 省略..." +
"CONTENT)" +
"values (?, ?, 省略..., empty_blob())";
//得到待处理文件
FormFile drawingFile = drawingVO.getDrawingFile();
//插入普通字段
pstmt = conn.prepareStatement(strSQLInsert);
//得到主键
iKey = Toolkit.getInstance().getNextKey(DrawingInfo.ID_STORE_KEY_DRAWING);
pstmt.setInt(1, iKey);
....省略其他set方法
pstmt.executeUpdate();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
strSQLUpdate =
"SELECT CONTENT FROM PROD_DRAWING WHERE DRAWING_ID ='" +
iKey + "'" + " FOR UPDATE";
//读出记录以增加图片Blob字段
rs = stmt.executeQuery(strSQLUpdate);
if(rs.next()) {
logger.debug("开始写入BLOB");
//这里不能用oracle.sql.BLOB,会报ClassCast异常
weblogic.jdbc.vendor.oracle.OracleThinBlob blob = (weblogic.jdbc.vendor.
oracle.
OracleThinBlob)rs.getBlob(1);
logger.debug("得到输出流");
OutputStream outStream = blob.getBinaryOutputStream();
InputStream fin = drawingFile.getInputStream();
logger.debug("开始分配缓存");
byte[] b = new byte[blob.getBufferSize()];
int len = 0;
while((len = fin.read(b)) != -1) {
logger.debug("正在写入BLOB流");
outStream.write(b, 0, len);
}
logger.debug("关闭所有流");
fin.close();
outStream.flush();
outStream.close();
}
rs.close();
conn.commit();
} catch(Exception ex) {
...省略
}finally {
DBUtil.destroyDB(rs, pstmt, conn);
}
return iKey;
}
2 读取BLOB字段的流程
从数据库中读出BLOB数据没有上述由于连接池的不同带来的差异,程序流程同插入BLOB字段,但是读BLOB就不用那么复杂了,只需要J2SE的标准类java.sql.Blob就可以取得输出流。
DAO中的核心代码:
public DrawingVO readDrawing(int drawingId) throws DrawingException {
PreparedStatement pstmt = null;
Connection conn = null;
DrawingVO objDrawingVO = null;
ResultSet rs = null;
//定义SQL语句
String strSQL = "SELECT * FROM PROD_DRAWING WHERE DRAWING_ID=?";
try {
conn = dataSource.getConnection();
pstmt = conn.prepareStatement(strSQL);
//设置参数
pstmt.setInt(1, drawingId);
//执行查询
rs = pstmt.executeQuery();
while(rs.next()) {
objDrawingVO = new DrawingVO();
objDrawingVO.setDrawingId(rs.getInt("DRAWING_ID"));
objDrawingVO.setDrawingName(rs.getString("DRAWING_NAME"));
...省略其他set方法
//set BLOB到VO中
objDrawingVO.setContent(rs.getBlob("CONTENT"));
}
} catch(Exception ex) {
...省略
}finally {
DBUtil.destroyDB(rs, pstmt, conn);
}
return objDrawingVO;
}
这样,传到Action中VO对象就包含这个BLOB对象了,然后需要在Action中对该对象转为输入流,可以选择文件输出流或Servlet输出流,根据具体情况定,这里选择文件输出流。
核心代码:
private String getBlobToFile(Blob blob, DrawingVO objDrawingVO) throws Exception {
InputStream ins = blob.getBinaryStream();
//用文件模拟输出流
String strFileName = objDrawingVO.getDrawingName() + "." +
objDrawingVO.getFileExtendName();
String strRootFilePath = this.getServlet().getServletContext().getRealPath("");
String strFilePath = "/temp/" + strFileName;
String contextFilePath = strRootFilePath + strFilePath;
//定义文件对象
File file = new File(this.getServlet().getServletContext().getRealPath("") + "/temp");
if(!file.exists()) {
file.mkdir();
}
//定义输出流
OutputStream fout = new FileOutputStream(contextFilePath, true);
//下面将BLOB数据写入文件
byte[] b = new byte[1024];
int len = 0;
while((len = ins.read(b)) != -1) {
fout.write(b, 0, len);
}
//依次关闭
fout.close();
ins.close();
return strFilePath;
}
最后,在Action中调用这个私有方法,完成读取操作。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caiyi0903/archive/2005/06/22/400060.aspx
分享到:
相关推荐
delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段delphi读写BLOB字段...
### Hibernate 对 Blob 类型字段进行数据添加 #### 知识点概述 在处理数据库操作时,经常需要存储二进制大对象(Binary Large Object,简称 BLOB),例如图像、视频等非文本数据。BLOB 类型是数据库系统中用于存储...
在C#中,我们使用`OracleDbType.Blob`类型来处理Blob字段。读取Blob字段时,可以创建一个`OracleBinary`对象,然后使用`GetValue`方法获取Blob数据。写入Blob字段时,先创建`OracleParameter`对象,将其Direction...
### ADO读写BLOB字段详解 #### 一、引言 在软件开发过程中,处理大量二进制数据(如图像、音频文件等)是非常常见的需求。这些数据通常被称为二进制大对象(BLOB,Binary Large Object)。本文将详细介绍如何使用...
* BLOB(Binary Large OBject)是一种数据库字段类型,用于存储二进制数据,如图片、音频、视频等。 * ORACLE数据库的BLOB字段可以存储大量的二进制数据,且性能优于LONG字段。 知识点3:坐标点的存储和读取 * 在...
本资源,演示了利用DataSnap 2009,通过方法调用方式,实现多层数据库应用的架构中,Blob字段的读写过程。 原创。 相关介绍文章: http://blog.csdn.net/ddqqyy/article/details/6646918
本篇文章将深入探讨如何在Delphi中对Oracle数据库的BLOB字段进行读写操作。 首先,你需要在Delphi项目中引入Oracle数据库访问的相关组件,如DBExpress或ADO。DBExpress是Delphi内置的一个轻量级数据库访问框架,而...
同时,我们也会探讨如何从blob字段中读取并恢复这些对象。 首先,对象序列化通常是通过自定义序列化函数或使用库(如Boost.Serialization或C++标准库中的`std:: stringstream`)来完成的。在这个场景中,我们可能...
BLOB字段在数据库中以字节流的形式存在,可以进行读写操作。 要实现批量导出BLOB字段生成图片,通常需要以下步骤: 1. **安装Oracle Client**:Oracle Client是与Oracle服务器通信的客户端工具,它提供了与数据库...
在Oracle数据库中,BLOB(Binary Large Object)和CLOB(Character Large Object)是两种用于存储大量数据的特殊字段类型。本篇文章将深入剖析如何使用MyBatis框架在Oracle数据库中对BLOB类型字段进行保存和读取。 ...
1. **查询BLOB数据**:使用SQL查询语句从Oracle数据库中选择含有BLOB字段的照片记录。例如: ```sql SELECT photo_blob FROM photos WHERE id = ; ``` 这里`photo_blob`是BLOB类型的列,`<photo_id>`是你想获取...
### SQL Server 数据库中存储 BLOB 类型数据详解 #### 一、背景介绍 在当前企业信息化建设过程中,经常会遇到需要处理大量非结构化数据的情况,例如图片、文档等二进制大对象(BLOB)。这类数据由于体积庞大且结构...
1. **创建Blob字段:** 首先需要在数据库表中定义一个Blob类型的字段。 2. **插入记录:** 将Blob字段与其它字段一起插入到表中。 3. **写入文件内容:** 将文件内容写入到Blob字段中。 ##### 示例代码(上传部分)...
Oracle 和 WebLogic 服务器在处理 BLOB(Binary Large Object)数据类型时,涉及的是数据库管理和Web应用程序中的数据存储与检索。BLOB 类型通常用于存储大量二进制数据,如图片、音频或视频文件。本篇文章将深入...
Oracle中的Blob字段类型是用于存储大量二进制数据的数据类型,比如图像、音频或大型文档。Blob代表Binary Large Object,其最大容量可达4GB。在Oracle数据库中,Blob与Clob(Character Large Object)、Bfile和Nclob...
在Delphi中,与数据库交互通常会用到ADO(ActiveX Data Objects)或DBX(Database Express)等组件库,它们支持BLOB字段的读写操作。 在实现这个功能时,TStream类起着核心作用。TStream是一个抽象类,它定义了读写...
【Java读写Oracle BLOB字段】在Java编程中,与Oracle...以上就是Java在Oracle数据库中读写BLOB字段的详细步骤和涉及的技术点。在实际开发中,可能需要根据具体需求进行调整和优化,例如添加错误处理机制,提高性能等。