Oracle数据库中BLOB字段的存取问题

以下的文章主要是对Oracle数据库中BLOB字段的存取问题的介绍,我在经常会碰到Oracle数据库中BLOB字段的存取这一问题,需求是将一个文件或者文件流存储到Oracle数据库里,Oracle8提供了Blob和Clob用来存储二进制大对象数据。

可是它和Java.sql.里面的Blob不兼容,经常导致Blob字段无法锁定或者操作失败,总之我总结了一些经验大家共享。

首先建立测试数据表

 

  1. drop table filelist;  
  2. commit;  
  3. CREATE TABLE SYSTEM.FILELIST (  
  4. "FILENAME" VARCHAR2(50) NOT NULL,  
  5. "FILESIZE" NUMBER(20) NULL,  
  6. "FILEBODY" BLOB NULL,  
  7. PRIMARY KEY("FILENAME"), UNIQUE("FILENAME")) ;  
  8. commit;  

 

测试过程,首先将硬盘文件读入Oracle数据库,然后再读出到硬盘的另一个新文件里,原码如下:

 

  1. import java.io.*;  
  2. import java.util.*;  
  3. import java.sql.*;  
  4. import oracle.sql.*;  
  5. import oracle.jdbc.driver.*;  
  6. import java.text.*;  
  7. public class test  
  8. {  
  9. public static void main(String args[]) throws java.io.IOException,java.sql.SQLException  
  10. {  
  11. dbBean db1=new dbBean();  
  12. /**  

 

*这里是我的数据联接Bean

*大家可以用自己的连接Bean

 

  1. */  
  2. byte a[]=null;  

 

**将测试文件test.doc读入此字节数组

 

  1. java.io.FileInputStream fin=null;  
  2. java.io.FileOutputStream fout=null;  
  3. oracle.jdbc.OracleResultSet ors=null;  

 

**这里rs一定要用Oracle数据库提供的

 

  1. oracle.jdbc.driver.OraclePreparedStatement opst=null

**PreparedStatement用

Oracle提供的

 

  1. try  
  2. {  
  3. java.io.File f1=new java.io.File("c:/temp/test.doc");  
  4. java.io.File f2=new java.io.File("c:/temp/testout.doc");  

**从BLOB读出的信息写

//入该文件,和源文件对比测试用

 

  1. fin=new java.io.FileInputStream(f1);  
  2. fout=new java.io.FileOutputStream(f2);  

 

int flength=(int)f1.length();//**读入文件的字节长度

 

  1. System.out.println("file length::"+flength);  
  2. a=new byte[flength];  
  3. int i=0;int itotal=0;  

 

/**将文件读入字节数组

 

  1. for (;itotal<flength;iitotal=i+itotal )  
  2. {  
  3. i=fin.read(a,itotal,flength-itotal);  
  4. }  
  5. fin.close();  
  6. System.out.println("read itotal::"+itotal);  

 

/**注意Oracle数据库的 BLOB一定要用EMPTY_BLOB()初始化

 

  1. String mysql="insert into filelist (FileName,FileSize,FileBody) values (?,?,EMPTY_BLOB())";  
  2. opst=(oracle.jdbc.driver.OraclePreparedStatement)db1.conn.prepareStatement(mysql);  
  3. opst.setString(1,"wordtemplate");  
  4. opst.setInt (2,flength);  
  5. opst.executeUpdate();  
  6. opst.clearParameters();  

 

/**插入其它数据后,定位BLOB字段

 

  1. mysql="select filebody from filelist where filename=?";  
  2. opst=(oracle.jdbc.driver.OraclePreparedStatement)db1.conn.prepareStatement(mysql);  
  3. opst.setString(1,"wordtemplate");  
  4. ors=(oracle.jdbc.OracleResultSet)opst.executeQuery();  
  5. if (ors.next())  
  6. {  

 

oracle.sql.BLOB blob=ors.getBLOB(1);/**得到BLOB字段

int j=blob.putBytes(1,a);/**将字节数组写入BLOB字段

 

  1. System.out.println("j:"+j);  
  2. db1.conn.commit();  
  3. ors.close();  
  4. }  
  5. System.out.println("insert into ok");  

 

byte b[]=null;/**保存从BLOB读出的字节

 

  1. opst.clearParameters();  
  2. mysql="select filebody from filelist where filename=?";  
  3. opst=(oracle.jdbc.driver.OraclePreparedStatement)db1.conn.prepareStatement(mysql);  
  4. opst.setString(1,"wordtemplate");  
  5. ors=(oracle.jdbc.OracleResultSet)opst.executeQuery();  
  6. if (ors.next())  
  7. {  
  8. oracle.sql.BLOB blob2=ors.getBLOB(1);  
  9. System.out.println("blob2 length:"+blob2.length());  

 

b=blob2.getBytes(1,flength);/**从BLOB取出字节流数据

 

  1. System.out.println("b length::"+b.length);  
  2. db1.conn.commit();  
  3. }  
  4. ors.close();  

 

/**将从BLOB读出的字节写入文件

 

  1. fout.write(b,0,b.length);  
  2. fout.close();  
  3. System.out.println("write itotal::"+b.length);  
  4. }  
  5. catch(Exception e)  
  6. {  
  7. System.out.println("errror :"+e.toString() );  
  8. e.printStackTrace();  
  9. }  
  10. finally  

 

{ /**关闭所有数据联接

 

  1. stmt.close();  
  2. db1.closeConn();  
  3. }  
  4. }  
  5. }  

 

编译运行在TomCat下调试通过。

需要注意的是Blob存取的过程,一般先存入和BLOB相关的控制数据,如文件的名字,然后查询定位BLOB字段,利用Oracle数据库Blob提供的方法:

 

  1. public int putBytes(long pos,byte bytes[])  
  2. public byte[] getBytes(long pos,byte bytes[])  

 

或者利用

 

  1. public OutputStream getBinaryOutputStream() throws SQLException  
  2. public InputStream getBinaryStream() throws SQLException  

 

因为利用输入输出流总归还是利用到字节数组缓冲流,所以就不举例子了。

【编辑推荐】

  1. Oracle 函数用法之decode解剖
  2. LTO归档解决方案容量、性能和功能介绍
  3. Oracle 函数用法之decode解剖
  4. Oracle字符集讨论的经典版
  5. Oracle表空间的设置问题的描述

 

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/273222.html<

(0)
运维的头像运维
上一篇2025-05-09 04:19
下一篇 2025-05-09 04:20

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注