Oracle的Blob字段比较特殊,他比long字段的性能要好很多,可以用来保存例如图片之类的二进制数据。
写入Blob字段和写入其它类型字段的方式非常不同,因为Blob自身有一个cursor,你必须使用cursor对blob进行操作,因而你在写入Blob之前,必须获得cursor才能进行写入,那么如何获得Blob的cursor呢?
这需要你先插入一个empty的blob,这将创建一个blob的cursor,然后你再把这个empty的blob的cursor用select查询出来,这样通过两步操作,你就获得了blob的cursor,可以真正的写入blob数据了。
看下面的JDBC的demo,把oraclejdbc.jar这个二进制文件写入数据库表javatest的content字段(这是一个blob型字段)
- importjava.sql.*;
-
importjava.io.*;
-
importoracle.sql.*;
-
publicclassWriteBlob{
- publicstaticvoidmain(String[]args){
- try{
- DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());
- Connectionconn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","fankai","fankai");
- conn.setAutoCommit(false);
- BLOBblob=null;
- PreparedStatementpstmt=conn.prepareStatement("insertintojavatest(name,content)values(?,empty_blob())");
- pstmt.setString(1,"fankai");
- pstmt.executeUpdate();
- pstmt.close();
- pstmt=conn.prepareStatement("selectcontentfromjavatestwherename=?forupdate");
- pstmt.setString(1,"fankai");
- ResultSetrset=pstmt.executeQuery();
- if(rset.next())blob=(BLOB)rset.getBlob(1);
- StringfileName="oraclejdbc.jar";
- Filef=newFile(fileName);
- FileInputStreamfin=newFileInputStream(f);
- System.out.println("filesize="+fin.available());
- pstmt=conn.prepareStatement("updatejavatestsetcontent=?wherename=?");
- OutputStreamout=blob.getBinaryOutputStream();
- intcount=-1,total=0;
- byte[]data=newbyte[(int)fin.available()];
- fin.read(data);
- out.write(data);
- fin.close();
- out.close();
- pstmt.setBlob(1,blob);
- pstmt.setString(2,"fankai");
- pstmt.executeUpdate();
- pstmt.close();
- conn.commit();
- conn.close();
- }catch(SQLExceptione){
- System.err.println(e.getMessage());
- e.printStackTrace();
- }catch(IOExceptione){
- System.err.println(e.getMessage());
- }
- }
- }
仔细看上例,分三步:
1、插入空blob
into javatest(name,content) values(?,empty_blob());
2、获得blob的cursor
select content from javatest where name= ? for update;
注意!!!必须加for update,这将锁定该行,直至该行被修改完毕,保证不产生并发冲突。
3、update javatest set content=? where name=
用cursor往数据库写数据
这里面还有一点要提醒大家:
JDK1.3带的JDBC2.0规范是不完善的,只有读Blob的接口,而没有写Blob的接口,JDK1.4带的JDBC3.0加入了写Blob的接口。你可以使用JDBC3.0的接口,也可以直接使用Oracle的JDBC的API,我在上例中使用了Oracle的JDBC的API。
另外要注意的是:
java.sql.Blob
oracle.sql.BLOB
注意看blob的大小写,是不一样的。写程序的时候不要搞混了。
下面看看用Hibernate怎么写,原理是一样的,也要分三步,但是代码简单很多
这是Cat对象定义
- packagecom.fankai;
-
importjava.sql.Blob;
-
publicclassCat{
- privateStringid;
- privateStringname;
- privatecharsex;
- privatefloatweight;
- privateBlobimage;
- publicCat(){}
- publicStringgetId(){returnid;}
- publicvoidsetId(Stringid){this.id=id;}
- publicStringgetName(){returnname;}
- publicvoidsetName(Stringname){this.name=name;}
- publicchargetSex(){returnsex;}
- publicvoidsetSex(charsex){this.sex=sex;}
- publicfloatgetWeight(){returnweight;}
- publicvoidsetWeight(floatweight){this.weight=weight;}
-
- publicBlobgetImage(){returnimage;}
- publicvoidsetImage(Blobimage){this.image=image;}
- }
这是Cat.hbm.xml
- <?xmlversion="1.0"?>
- <!DOCTYPEhibernate-mappingSYSTEM"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
-
<hibernate-mapping>
- <classname="com.fankai.Cat"table="cat">
- <idname="id"unsaved-value="null">
- <generatorclass="uuid.hex"/>
- </id>
- <propertyname="name"length="16"not-null="true"/>
- <propertyname="sex"length="1"not-null="true"/>
- <propertyname="weight"/>
- <propertyname="image"/>
- </class>
-
</hibernate-mapping>
下面是完整的用Hibernate写入Blob的例子,相比JDBC,已经简单轻松多了,也不用写那些Oracle特殊的sql了:
- packagecom.fankai;
-
importjava.sql.Blob;
-
importnet.sf.hibernate.*;
-
importoracle.sql.*;
-
importjava.io.*;
-
publicclassTestCatHibernate{
- publicstaticvoidtestBlob(){
- Sessions=null;
- byte[]buffer=newbyte[1];
- buffer[0]=1;
- try{
- SessionFactorysf=HibernateSessionFactory.getSessionFactory();
- s=sf.openSession();
- Transactiontx=s.beginTransaction();
- Catc=newCat();
- c.setName("Robbin");
- c.setImage(Hibernate.createBlob(buffer));
- s.save(c);
- s.flush();
- s.refresh(c,LockMode.UPGRADE);
- BLOBblob=(BLOB)c.getImage();
- OutputStreamout=blob.getBinaryOutputStream();
- StringfileName="oraclejdbc.jar";
- Filef=newFile(fileName);
- FileInputStreamfin=newFileInputStream(f);
- intcount=-1,total=0;
- byte[]data=newbyte[(int)fin.available()];
- fin.read(data);
- out.write(data);
- fin.close();
- out.close();
- s.flush();
- tx.commit();
-
- }catch(Exceptione){
- System.out.println(e.getMessage());
- }finally{
- if(s!=null)
- try{
- s.close();
- }catch(Exceptione){}
- }
-
- }
- }
分享到:
相关推荐
在IT领域,尤其是在数据库...总之,无论是使用JDBC还是Hibernate,正确处理Oracle中的BLOB字段都是至关重要的,尤其是在处理大量二进制数据的应用场景下。掌握上述流程和技巧,能够有效提升数据操作的效率和安全性。
本篇将详细介绍如何使用JDBC(Java Database Connectivity)与Hibernate框架来操作Oracle数据库中的BLOB字段。 首先,Oracle数据库的BLOB字段提供了对大对象的高效存储,它的性能优于LONG字段,尤其适合存储大容量...
总结来说,无论是通过JDBC还是Hibernate,写入Oracle数据库的Blob字段都需要先创建一个空Blob,然后获取其cursor,最后将二进制数据写入Blob。在JDBC中,这个过程涉及多个SQL语句和流操作;而在Hibernate中,通过ORM...
在Java的数据库操作中,`CLOB...总之,无论是使用JDBC还是Hibernate,处理`CLOB`和`BLOB`字段都需要特殊的处理方式,尤其是在Oracle等数据库中。了解这些处理方法对于开发涉及大数据量文本和二进制数据的应用至关重要。
使用JDBC(Java Database Connectivity)API建立与数据库的连接。首先,需要引入数据库驱动,例如MySQL、Oracle或PostgreSQL的驱动。然后,使用`DriverManager.getConnection()`方法创建连接。 2. **准备SQL语句**...
在Java的持久化框架Hibernate中,处理大数据类型如...通过以上方法,开发者可以在Hibernate中有效地处理Oracle数据库中的Clob和Blob字段。了解并熟练运用这些技术,能帮助我们构建高效、稳定且易于维护的数据存储系统。
这里我们关注的是如何使用Hibernate框架将图片这种二进制文件插入到数据库中。Hibernate作为Java领域的一个流行ORM(对象关系映射)框架,能够简化数据库操作,使开发者可以使用面向对象的方式来处理数据。 首先,...
在Struts2 Action中,可以使用JDBC、ORM框架(如Hibernate)或MyBatis来执行SQL语句,将文件内容写入数据库。 5. **安全性考虑**:在上传过程中,要防止文件注入攻击,需要对上传的文件名和类型进行验证。同时,...
本篇文章将深入探讨如何在 Oracle 数据库与基于 WebLogic 的应用中读写 BLOB 数据。 首先,Oracle 数据库提供了多种操作 BLOB 值的方法。在 SQL 查询中,你可以使用 `SELECT BLOB_COLUMN FROM TABLE` 来读取 BLOB ...
接下来,我们将深入探讨在Hibernate中操作Oracle和MySQL数据库中的Blob字段: 1. **配置Hibernate**:在项目中集成Hibernate,你需要创建一个`hibernate.cfg.xml`配置文件,配置数据库连接信息,包括数据库URL、...
@Lob 注解可以与 @Basic 注解结合使用,以确保正确地读取和写入 Clob 类型的数据。例如: ``` @Column(name="SUBSTANCE", columnDefinition="CLOB", nullable=true) @Basic(fetch = FetchType.EAGER) @Lob private ...
读取时,Hibernate会自动将数据库中的Clob对象返回,你可以通过调用Clob的`getSubString`或`getCharacterStream`方法来获取内容。 4.2.4 **删除(Delete)**: 删除操作与普通对象的删除相同,只需调用Session的`...
- **ORM框架**:Hibernate等ORM框架能够将数据库操作对象化,处理Blob数据更加方便。 5. **image.rar文件** 这个rar文件可能包含了演示代码、示例图片或者其他相关资源,解压后可以参考和学习如何在实际项目中...
本文选用的数据库为Oracle 9i,当然你可以在不改动代码的情况下,通过配置文件的调整将其移植到任何具有Blob字段类型的数据库上,如MySQL,SQLServer等。 总体实现 上传文件保存到T_FILE表中,T_FILE表结构...
在存储文件时,使用PreparedStatement的setBlob方法将文件内容写入BLOB字段。 最后,下载文件的过程相对简单。用户发起下载请求时,Struts2 Action根据文件ID从数据库中获取文件元数据,然后通过Hibernate的Session...
5. **持久化到数据库**:使用Hibernate或JDBC API将二进制流写入数据库。在Hibernate中,你可以定义一个实体类,包含一个`Blob`类型的属性,并在保存实体时将二进制流转换为`Blob`对象。 6. **查询与显示**:当需要...
在JDBC操作中,可以使用`PreparedStatement.setBlob()`方法将Blob对象设置为SQL语句的参数,然后执行插入操作。 4. **文件下载**: 当需要从数据库中检索Blob对象并提供给客户端下载时,可以使用`ResultSet....
建立与Oracle数据库的连接后,创建一个PreparedStatement,将二进制数据作为参数传入,如下所示: ```java String sql = "INSERT INTO images (id, image_data) VALUES (?, ?)"; PreparedStatement pstmt = ...