日期:2014-05-16  浏览次数:20576 次

Hibernate实现Clob和Blob对象的存取

?

TUser user  = new  TUser(); 
   
  user.setAge( new  Integer( 20 )); 
   
  user.setName( " Shark " ); 
   
  FilelnputStream imgis  = new  FileinputStream( " C:\\inimage.jpg "  
   
  Blob img  =  Hibernate.createBlob(imgis); 
   
  user.setlmage(img); 
   
  Clob resume  =  Hibernate.createClob( " This is Clob " ); 
   
  user. setResume(resume); 
   
  Transaction tx  =  session.beginTransaction(); 
   
  session.save(user); 
 
  tx.commit(); 

?上面的代码中,我们通过Hibemate.createBlobHibemate.createClob创建了对应的BlobClob对象。其中Blob对象基于一个FileInputStream构建,而Clob对象基于一个字符串构建。

?

?

完成了写入操作,对应的读取操作代码如下:

?

 //  假设库表记录的id字段等于3  
TUser user = (TUser)  session.load(TUger.elaa., load(TUser. class ,   new  Integer( 3 )); 
Clob resume = user.getResume(); 
//  通过Clob.getSubString()方法获取Clob字段内容  
System.out.println( " User resume=> " + resume.getSubString( 1 ,( int )resume.length())); 
Blob img  =  user.getImage(); 
//  通过Blob.getBinaryS=ream()方法获取二进制流  
InputStream is  =  img.getBinaryStream(); 
FileOutputStream fos = new  FileOutputStream( " C:\\outimage.jpg " ); 
byte [] buf = new   byte ( 102400 ); 
int  len; 
while ((len  =  is.read(buf)) !=- 1 ) { 
fos.write(buf, 0 ,len); 
}  
fos.close(); 
is.close(); 

?通过上面的代码,我们完成了针对SQLServerBlob/Clob型字段操作.看起来非常简单,不过,并非侮种数据库都如此友善。让我们接着来看看Oracle数据库下的Blob/Clob字段读写,

?

通过修改hibernate.cfg.xml中的Dialect配置完成数据库切换后,我们再次运行上面的TUser对象保存例程。

程序运行期间抛出异常:

?

Hibernate:select hibernate_sequence.nextval from dual
Hibernate:insert into T_USER (name, age,  image,resume. id) values(?, ?, ?, ?, ?)
17:27:24,161 ERROR JDBCExceptionReporter:58 - - 不允许的操作: Streams type cannot be used in batching
17:27:24,171 ERROR Sessionlmpl:2399 - Could not synchronize database state with session
net.sf.hibernate.exception.GenericJDBCException:could not insert:[com.redsaga.hibernate.db.entity.TUser#6]
...

?观察异常信息:streams type cannot be used in batching.这意味着Oracle JDBC不允许流操作以批量方式执行(Oracle CLOB采用流机制作为数据读写方式)

?

这种错误一般发生在hibernate.cfg.xml中的hibernate jdbc.batch_size