保存文件等二进制大对象到oracle数据库中的解决方法

本文介绍如何使用Hibernate将文件作为二进制大对象保存到Oracle数据库的方法,包括前端页面设计、Action处理流程及后台保存逻辑。
使用hibernate保存文件等二进制大对象到oracle数据库中的解决方法
                                      
 

1.VO,PO准备

首先在数据库中定义要保存的字段为Blob类型,同时map的对应hbm文件中对应列应该为java.sql.Blob类型,所以生成的PO对应字段也应该为java.sql.Blob,(不是oracle.sql.BLOB)。

对于前台的值对象VO中,对应字段定义为byet[],当然也可以设置为InputStream,由后台进行处理,但是不应直接设置为blob类型,因为dao在写操作时需要用数据流进行写入。

2.前台处理

首先是页面的定义

<input type=”file” name=”upFile”/>

或<html:file property=”upFile”>

然后是Action 对应Form的定义,应该存在一个FormFile类型的字段,以获取页面上传的文件对象,名称和页面上定义的文件控件对应,比如:upFile.

最后是Action中的实现:

首先通过form获取FormFile对象,通过FormFile对象获取对应文件的大小,和对应的输入流InputStream,利用com.westerasoft.common.util.FileUtil中的getByte方法,将InputStream转为byte[],设置在VO对象中,调用后台方法进行保存.前台处理完成。下面是示例代码:

                       FileUpForm fileform = (FileUpForm)form;           //           FormFile file = fileform.getFile();           //           int size = file.getFileSize();           //           InputStream stream = file.getInputStream();           //           String fileName = file.getFileName();           //           PictureFileVO vo = new PictureFileVO();           vo.setPictureName(fileName);           //           vo.setContent(FileUtil.getBytes(stream,size));           //        SingleWellManageService.addPictureFile(vo);3.由于oracle的Blob字段的保存,比较特殊,首先必须先初始化对应的Blob字段,既第一次保存时,应该保存空的Blob对象到数据库(empty_blob()),然后再进行更新,在更新的过程中必须对当前记录进行锁定,更新时需要使用输出流的方式。对于使用Hibernate来说,比JDBC简单一些,保存时不能简单使用hibernate的save方法,那样会造成保存只能保存4K以下的文件,有的说是因为oracle9i之前的驱动问题,使用10g可解决问题,未进行尝试。下面是实现的简单示例:  

dao = new SwWellPictureFileDAO();

//获取session

        Session s = null;

        try

        {

            //获取实例

            s = dao.getSession();

           

//初始化设置空的Blob       

            po.setContent(BLOB.empty_lob());

            //第一次保存,初始化blob

            s.save(po);

            s.flush();

            s.refresh(po, LockMode.UPGRADE); //Blob更新之前必须锁定

            //将当前PO的blob字段与OutputStream关联

            weblogic.jdbc.vendor.oracle.OracleThinBlob tempBlob =

        (weblogic.jdbc.vendor.oracle.OracleThinBlob)po.getContent();

            OutputStream out = tempBlob.getBinaryOutputStream();

            //将前台的byte[]写入流

            out.write(content);

            out.close();

            //数据持久

            s.flush();

            return po.getPkPicturefile().intValue();

        }

        catch (Exception e)

        {

            throw new HibernateException("提交文件信息出错");

        }

        finally

        {

            //关闭session

            if (s != null)

            {

                s.close();

            }

     }

<think>我们正在处理用户关于如何将文件二进制形式保存数据库的问题。用户已经提供了两个引用,引用1展示了一个Java代码片段,其中使用update方法二进制数据保存数据库;引用2描述了如何将文件转为二进制流并保存到Blob类型的数据库列,以及如何读取它。 用户明确要求将文件二进制形式保存数据库,因此我们需要提供清晰的步骤和方法。根据引用内容,我们主要关注Java语言的操作。 核心步骤: 1. 读取文件二进制数据(字节数组或二进制流)。 2. 使用JDBC将二进制数据保存数据库的Blob类型字段。 另外,注意引用1中使用了预处理语句(PreparedStatement)来执行更新,引用2则描述了如何从结果集中读取Blob数据。 由于用户可能使用不同的数据库(如MySQL、Oracle等),但操作Blob的方式类似,我们以通用的JDBC操作为例。 具体步骤: 1. 建立数据库连接。 2. 创建预处理语句,并使用setBlob或setBytes方法设置二进制参数。 3. 执行SQL语句。 同时,我们可能需要考虑大文件的处理,可以使用流的方式以避免内存溢出。 因此,回答将包括: - 使用字节数组(适合小文件) - 使用流(适合大文件) 另外,我们还需考虑如何从数据库中读取二进制文件并还原为文件。 </think>### 如何将文件二进制形式保存数据库 #### 核心步骤 1. **读取文件二进制流** 使用 Java I/O 流读取文件并转换为二进制数据: ```java File file = new File("yourfile.txt"); byte[] fileData = Files.readAllBytes(file.toPath()); ``` 2. **数据库表设计** 创建包含 `BLOB`(二进制大对象)类型的列: ```sql CREATE TABLE resources ( id INT PRIMARY KEY AUTO_INCREMENT, file_name VARCHAR(255), binary_data BLOB -- 关键字段 ); ``` 3. **JDBC 写入数据库** 通过 `PreparedStatement` 插入二进制数据: ```java String sql = "INSERT INTO resources (file_name, binary_data) VALUES (?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, "yourfile.txt"); pstmt.setBytes(2, fileData); // 核心写入操作 pstmt.executeUpdate(); } ``` #### 关键注意事项 1. **大文件处理** 超过 1MB 的文件建议使用流式传输,避免内存溢出: ```java try (FileInputStream fis = new FileInputStream(file)) { pstmt.setBinaryStream(2, fis, (int) file.length()); } ``` 2. **数据类型选择** - MySQL: `BLOB`(最大 65KB)或 `LONGBLOB`(最大 4GB) - Oracle: `BLOB` - PostgreSQL: `BYTEA` 3. **读取二进制数据** 从数据库还原文件: ```java Blob blob = resultSet.getBlob("binary_data"); try (InputStream is = blob.getBinaryStream()) { Files.copy(is, Paths.get("restored_file.txt")); } ``` ### 性能优化建议 - **分块传输**:对超大文件使用 `setBinaryStream(int, InputStream, int)` 分块写入 - **索引优化**:为文件名字段添加索引,但避免索引 `BLOB` 列 - **内存管理**:用 `try-with-resources` 确保流及时关闭,防止内存泄漏 > 示例基于 JDBC 标准 API,实际需根据数据库驱动调整语法[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值