Oracle数据库中BLOB字段的存取问题
创始人
2024-06-29 15:00:19
0次

以下的文章主要是对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
  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表空间的设置问题的描述

 

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
如何更省钱? 近期特价热门硒鼓... 如今激光打印设备已经成为商务或企业的绝对主力办公设备,但采购者往往忽视了激光打印设备所用的耗材,相对...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...