`
friping
  • 浏览: 133871 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

hibernate 操作clob,blob对象

阅读更多

转自:http://hpingliu.blog.ccidnet.com/blog-htm-do-showone-type-blog-itemid-144245-uid-48802.html]

作为测试,我们新建一个TUser对象,其image属性中,保存了一个图片文件的二进制内容。而其resume属性,我们以一个简单的字符串作为填充。


1 TUser user = new TUser();
2
3 user.setAge( new Integer( 20 ));
4
5 user.setName( " Shark " );
6
7 FilelnputStream imgis = new FileinputStream( " C:\\inimage.jpg "
8
9 Blob img = Hibernate.createBlob(imgis);
10
11 user.setlmage(img);
12
13 Clob resume = Hibernate.createClob( " This is Clob " );
14
15 user. setResume(resume);
16
17 Transaction tx = session.beginTransaction();
18
19 session.save(user);
20
21 tx.commit();
22
23

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

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

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




通过上面的代码,我们完成了针对SQLServer的Blob/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设定大于0的情况,将hibernate.jdbc.batch_size修改为0即可消除。

<hibernate-configuration>
<session-factory>
...
<property name='hibernate. jdbc.batch_size">0</property>
...
</session-factory>
</hibernate-configuration>

再次尝试启动代码,发现依然无法成功运行,抛出异常如下:

Java代码 复制代码
  1.     
  2. Hibernate: select hibernate_sequence.nextval from dual    
  3. Hibernate: insert into T--USER (name, age, image,resume,id) values(?,?,?,?,?)    
  4. 19:02:21,054 ERROR JDBCExceptionReporter:58 一IO异常:Connection reset bypeer: socket write error    
  5. 19:02:21,054 ERROR JDBCExceptionReporter:58 一I。异常:Connection reset by peer:socket write error    
  6. 19:02:21 。064 ERROR JDBCExceptionReporter:58一Io异常:Connection reset by peer: socket wr主to error    
  7. 19:02:21,064 ERROR Sessionlrnpl:2399 一Could not synchronize database state with session    
  8. net.sf.hibernate.exception.GenericJDSCException: could not insert:[com.redsaga.hibernate.db.entity.TUser#27]    
  9. ...   
 
Hibernate: select hibernate_sequence.nextval from dual 
Hibernate: insert into T--USER (name, age, image,resume,id) values(?,?,?,?,?) 
19:02:21,054 ERROR JDBCExceptionReporter:58 一IO异常:Connection reset bypeer: socket write error 
19:02:21,054 ERROR JDBCExceptionReporter:58 一I。异常:Connection reset by peer:socket write error 
19:02:21 。064 ERROR JDBCExceptionReporter:58一Io异常:Connection reset by peer: socket wr主to error 
19:02:21,064 ERROR Sessionlrnpl:2399 一Could not synchronize database state with session 
net.sf.hibernate.exception.GenericJDSCException: could not insert:[com.redsaga.hibernate.db.entity.TUser#27] 
... 


为什么会出现这样的情况?
问题出在Oracce中Blob/Clob字段独特的访问方式,Oracle Blob/Clob字段本身拥有一个游标(cursor) , JDBC必须通过游标对Blob/ Clob字段进行操作,在Blob/Clob字段被创建之前,我们无法获取其游标句柄,这也就意味着,我们必须首先创建一个空Blob/Clob字段,再从这个空Blob/Clob字段获取游标,写入我们所期望保存的数据。
如果用JDBC代码来表示这个过程,则得到如下代码:

Java代码 复制代码
  1.     
  2. //... 获取JDBC连接    
  3. dbconn.setAutoCommit(falee);    
  4. // =======插入数据,BLOB CLOB字段插入空值    
  5. PreparedStatenent preStmt=    
  6. dbconn.prepareStatement(    
  7. "insert into T_USER (name, age, id,image,resume) values    
  8. (?,?,?,?,?)");    
  9. preStmt.setString(1,"Shark");    
  10. preStmt.setInt(2,20);    
  11. preStmt.setInt(3,5);    
  12. // 通过oracle.sgl.BLOB/CLOB.empty_lob()方法构造空Blob/Clob对象    
  13. preStmt.setBlob(4 ,oracle.sgl.BLOB.empty_lob());    
  14. preStmt.setClob(5,oracle.sgl.CLOB.empty_lob());    
  15. preStmt.executeUpdate();    
  16. preStmt.close():    
  17. //========== 再次从库表读出,获得Blob/Clob句柄    
  18. preStmt=    
  19. dbconn.prepareStatement(    
  20. "select image,resume from T_USER where id=?for update');    
  21. preStmt.setint(l,5);    
  22. ResultSet rset=preStmt.executeQuery();    
  23. // 注意我们这里需要引用Oracle原生BLOB定义,如果使用了Weblogic JDBC Vendor    
  24. // 则应使用weblogic.jdbc.vendor.oracle. OracleThinBLob/OracleThinCLOb    
  25. rset.next();    
  26. oracle.sql.BLOB imqBlob = (oracle.sql.BLOB) rset.getBlob(1);    
  27. oracle.sql.CLOB resClob = (oracle.sql.CLOB) rset.getClob(2);    
  28. //======= 将二进创数据写入Blob    
  29. FileInputStream inStream = new FileinputStream("c\\inimage.jpg");    
  30. OutputStream outStream = imgBlob.getBinaryOutputStream();    
  31. byte[] buf=new byte[10240];//10K 读取缓存    
  32. int len;    
  33. while((len=inStream.read(buf))>0){    
  34. outStream.write(buf,0,len);    
  35. }    
  36. inStream.close();    
  37. outStream.close():    
  38. //======= 将字符串写入Clob    
  39. resClob.putString(1 ,"This is my Glob"    
  40. //======= 将Blob/Clob字段更新到数据序    
  41. preStmt= dbconn.prepareStatement("update T_USER set image=?, resume=? where id=?");    
  42. preStmt.setBlob(1,imgBlob);    
  43. preStmt.setClob(2,resClob):    
  44. preStmt.setlnt(3 ,5);    
  45. preStmt.executeUpdate();    
  46. preStmt.close():    
  47. dbconn.commit();    
  48. dbconn.close():   
 
//... 获取JDBC连接 
dbconn.setAutoCommit(falee); 
// =======插入数据,BLOB CLOB字段插入空值 
PreparedStatenent preStmt= 
dbconn.prepareStatement( 
"insert into T_USER (name, age, id,image,resume) values 
(?,?,?,?,?)"); 
preStmt.setString(1,"Shark"); 
preStmt.setInt(2,20); 
preStmt.setInt(3,5); 
// 通过oracle.sgl.BLOB/CLOB.empty_lob()方法构造空Blob/Clob对象 
preStmt.setBlob(4 ,oracle.sgl.BLOB.empty_lob()); 
preStmt.setClob(5,oracle.sgl.CLOB.empty_lob()); 
preStmt.executeUpdate(); 
preStmt.close(): 
//========== 再次从库表读出,获得Blob/Clob句柄 
preStmt= 
dbconn.prepareStatement( 
"select image,resume from T_USER where id=?for update'); 
preStmt.setint(l,5); 
ResultSet rset=preStmt.executeQuery(); 
// 注意我们这里需要引用Oracle原生BLOB定义,如果使用了Weblogic JDBC Vendor 
// 则应使用weblogic.jdbc.vendor.oracle. OracleThinBLob/OracleThinCLOb 
rset.next(); 
oracle.sql.BLOB imqBlob = (oracle.sql.BLOB) rset.getBlob(1); 
oracle.sql.CLOB resClob = (oracle.sql.CLOB) rset.getClob(2); 
//======= 将二进创数据写入Blob 
FileInputStream inStream = new FileinputStream("c\\inimage.jpg"); 
OutputStream outStream = imgBlob.getBinaryOutputStream(); 
byte[] buf=new byte[10240];//10K 读取缓存 
int len; 
while((len=inStream.read(buf))>0){ 
outStream.write(buf,0,len); 
} 
inStream.close(); 
outStream.close(): 
//======= 将字符串写入Clob 
resClob.putString(1 ,"This is my Glob" 
//======= 将Blob/Clob字段更新到数据序 
preStmt= dbconn.prepareStatement("update T_USER set image=?, resume=? where id=?"); 
preStmt.setBlob(1,imgBlob); 
preStmt.setClob(2,resClob): 
preStmt.setlnt(3 ,5); 
preStmt.executeUpdate(); 
preStmt.close(): 
dbconn.commit(); 
dbconn.close(): 



上面的代码说明了Oracle中Blob/Clob字段操作的一般机制,那么,基于Hibernate的持久层实现中,应该如何对Blob/Clob字段进行处理?
我们知道,Hibernate底层数据访问机制仍然是基于JDBC实现,那么也就意味着我们必须在Hibernate中模拟JDBC的访问流程:

Java代码 复制代码
  1.     
  2. TUser user=new TUser();    
  3. user.setAge(new Integer(20));    
  4. user.setName("Shark');    
  5. user.setImage(Hibernate.createSlob(new byte [1])):    
  6. user.setResume(Hibernate.createClob(" "));// 注意这里的参教是一个空格    
  7. Transaction tx=session.beginTransaction();    
  8. session.save(user):    
  9. // 调用flush方法,强制Hibernate立即执行insert sql    
  10. session.flush();    
  11. // 通过refresh方法,强制Hibernate执行select for update    
  12. session.refresh(user, LockMode.UPGRADE);    
  13. // 向Blob写入实际内容    
  14. oracle.sql.BLOB blob=(oracle.sql.BLOB)user.getImage();    
  15. OutputStream out=blob. getBinaryOutputStream();    
  16. FileInputStream imgis=new FileInputStream("C:\\inimage.jpg");    
  17. byte[] buf=new byte[10240];//10K 缓存    
  18. int len;    
  19. while((len=imgis.read(buf))>0){    
  20. out.write(buf,0,len);    
  21. }    
  22. imgis.close();    
  23. out.close();    
  24. // 向Clob写入实际内容    
  25. oracle.sql.CLOB clob=(oracle.sgl.CLOB) user.getResume();    
  26. java.io.Writer writer = clob.getCharacterOutputStream();    
  27. writer.write("this is my resume');    
  28. writer.close();    
  29. session.save(user);    
  30. tx.commit();    
  31.   
  32. <PRE class=java name="code">    
  33.   
  34. 实际应用中,对于Clob字段,我们可以简单地将其映射为String类型,不过在这种情况下需要注意,Oracle Thin Driver对Clob字段支持尚有欠缺,当Clob内容超出4000字节时将无法读取,而Oracle OCI Driver(需要在本地安装Oracle客户端组件)则可以成功地完成大容量Clob字段的操作。    
  35. 上面的代码中,我们通过Session.save/flush/refresh方法的组合使用,实现了上面JDBC代码中的Blob/Clob访问逻辑。    
  36. Blob/Clob 字段的Hibernate保存实现如上所述,相对来讲,读取则没有太多的障碍,之前的读取代码依然可以正常运行。    
  37. 对于上面的实现,相信大家都感觉到了一些Bad Smell,如果Blob/Clob字段普遍存在,那么我们的持久层逻辑中可能遍布如此复杂的数据存储逻辑、并与数据库原生类紧密祸    
  38. 如何解决这些问题?    
  39. 回忆之前关于自定义数据类型的讨论。通过自定义数据类型我们可以对数据的通用特征进行抽象,那么,对于Oracle的Blob/Clob字段,我们是否可以也对其进行抽象,并以其作为所有Oracle Blob/Clob字段的映射类型?    
  40. 下面的StringClobType实现了这一目标:    
  41.   
  42. <PRE class=java name="code">    
  43. public class StringClobType implements UserType{    
  44. private static final String ORACLE_DRIVER_NAME="Oracle JDBC driver";    
  45. private static final int ORACLE_DRIVER_MAJOR_VERSION=9;    
  46. private static final int ORACLE_DRIVER_MINOR_VERSION=0;    
  47. public int[] sqlTypes(){    
  48. return new int[] {Types.CLOB};    
  49. }    
  50. public Class returnedClass{    
  51. return String.class;    
  52. }    
  53. public boolean equals(Object x, object y){    
  54. return org.apache.commons.lang.ObjectUtils.equals(x, y);    
  55. }    
  56. public Object nullSafeGet(ResultSet rs, String[] names, Object owner)    
  57. throws HibernateException,SQLException{    
  58. Clob clob=rs.getClob(names(O]);    
  59. return(clob==null ? null:clob.getSubString(l, (int) clob.length())):    
  60. }    
  61. public void nullSafeSet(PreparedStatement st ,Object value, int index)    
  62. throws HibernateException, SQLException{    
  63. DatabaseMetaData dbMetaData=st.getConnection().getMetaData();    
  64. if (value==null)    
  65. st.setNull(index, sqiTypes()(0));    
  66. else    
  67. // 本实现仅仅适用于Oracle数据序9.0以上版本    
  68. if    
  69. (ORACLE_DRIVER_NAME.equals(dbMetaData.getDriverName( ,))(    
  70. if((dbMetaData.getDriverMajorVersion()    
  71. >=ORACLE-DRIVER-MAJOR-VERSION)    
  72. &&(dbMetaData.getDriverMinorVersion()    
  73. >=ORACLE-DRIVER-MINOR-VERSION)) {    
  74. try {    
  75. // 通过动态加载方式进免编译期对Oracle JDBC的依赖    
  76. Class oracleClobClass=Class.forName('oracle.sgl.CLOB");    
  77. // 动态调用createTemporary方法    
  78. Class partypes[]=new Class[3];    
  79. partypes[0]=Connection.class;    
  80. partypes[1]=Boolean.TYPE;    
  81. partypes(2]=Integer.TYPE;    
  82. Method createTemporaryMethod=    
  83. oracleClobClass.getDeclaredMethod(    
  84. "createTemporaxy “,    
  85. partypes);    
  86. Field durationSessionField=    
  87. oracleClobClass.getField("DURATION-SESSION");    
  88. Object arglist[]=new 0bject[3]:    
  89. Connection conn=    
  90. st.getConnection().getMetaData().getConnection();    
  91. // 数据库连接类型必须为OracleConnection    
  92. // 莱些应用服务器会使用自带Oracle JDBC Wrapper,如Weblogic    
  93. // 这里需要特别注意    
  94. Class oracleConnectionClass=    
  95. Class.forName("oracle.jdbc.OracleConnection");    
  96. if(!oracleConnectionClass    
  97. .isAssignableFrom(conn.getClass())){    
  98. throw new HibernateException(    
  99. "Must be a oracle.jdbc.OracleConnection:.    
  100. +conn.getClass().getName());    
  101. }    
  102. arglist[0] = conn;    
  103. arglist(1] = Boolean.TRUE;    
  104. arolist[2] = durationSessionField.get(null);    
  105. Object tempClob =createTemporaryMethod.invoke(null,arglist);    
  106. partypes=new Class[l];    
  107. partypes[0]=Integer.TYPE;    
  108. Method openMethod =oracleClobClass.getDeclaredMethod("open",partypes);    
  109. Field modeReadWriteField =oracleClobClass.getField("MODE_READWRITE");    
  110. arglist = new Object(l];    
  111. arglis[0] = modeReadWriteField.get(null);    
  112. openMethod.invoke(tempClob, arglist);    
  113. Method getCharacterOutputStreamMethod=oracleClobClass.getDeclaredMethod("getCharacterOutputStream',null) ;    
  114. // call the getCharacterOutpitStream method    
  115. Writer tempClobWriter =(Writer)getCharacterOutputStreamMethod.invoke(tempClob,null);    
  116. // 将参数写入Clob    
  117. tempClobwriter.write((String) value);    
  118. tempClobWriter.flush();    
  119. tempClobWriter.Close();    
  120.   
  121. // close clob    
  122. Method closeMethod=oracleClobClass.getDeclaredMethod("close"null);    
  123. closeMethod.invoke(tempClob, null);    
  124. st.setClob(index, (Clob) tempClob);    
  125. )catch (ClassNotFoundException e){    
  126. throw new HibernateException("Unable to find a required class.\n"+e.getMessage()):    
  127. }catch (NOSuchMethodException e){    
  128. throw new HibernateException("Unable to find a required method.\n"+e.getMessage()):    
  129. }catch (NoSuchFieldException e){    
  130. throw new HibernateException("Unable to find a required field.\n"+e.getMessage());    
  131. }catch (IllegalAccessException e){    
  132. throw new HibernateException("Unable to access a required method or field.\n"+e.getMessage());    
  133. catch (InvocationTargetException e){    
  134. throw new HibernateException(e.getMessage());    
  135. catch (IOException e){    
  136. throw new HibernateException(e.getMessage());    
  137. }    
  138. else {    
  139. throw new HibernateException(    
  140. "No CLOBS support.Use driver version"    
  141. +ORACLE_DRIVER_MAJOR_VERSION    
  142. +" ,minor"    
  143. +ORACLE_DRIVER_MINOR_VERSION);    
  144. }    
  145. }else {    
  146. String str = (String) value;    
  147. StrinaReader r = new StringReader(str);    
  148. St.setCharacterStream(index, r, str.length());    
  149. }    
  150. }    
  151. public Object deepCopy(Object value){    
  152. if(value==null)    
  153. return null;    
  154. return new String((String) value);    
  155. }    
  156. public boolean isMutable(){    
  157. return false    
  158. }    
  159. }    
  160.   
  161.  </PRE>   
  162. <BR>   
  163. <BR>上面这段代码,重点在于nullSafeSet方法的实现,nullSafeSet中通过Java Reflection机制,解除了编译期的Oralce JDBC原生类依赖。同时,借助Oracle JDBC提供的原生功能完成了Clob字段的写入,Clob字段的写入操作由于涉及特定数据库内部实现细节,这里就不多费唇舌,大家可参见Oracle JDBC Java Doc.    
  164. <BR>这段代码是由笔者根据Ali Ibrahim, Scott Miller的代码修改而来的(原版请参见httpJ/www.hibemate, org /56.html ),支持Oracle 9以上版本,Oracle 8对应的实现请参见上述网址。    
  165. <BR>同样的道理,读者可以根据以上例程,编写自己的ByteBlobType以实现byte[]到Blob的映射。    
  166. <BR>另外,此代码必须运行在最新版的Oracle JDBC Driver上(笔者所用版本为Oracle9i9.2.0.5 for JDK1.4,如果使用9.2.0.3或之前版本则在新建l更却删除数据时可能会遇到“nomore data read from socket”错误)。   
  167. <BR>    
  168. <BR>  </PRE
分享到:
评论

相关推荐

    Hibernate对BLOB CLOB操作

    本文将深入探讨Hibernate如何进行BLOB和CLOB的操作,以及相关的核心概念和实践示例。 BLOB用于存储二进制数据,例如图片或文档,而CLOB则用于存储大量的字符数据,如长篇的文本内容。在数据库中,这两个类型通常...

    Hibernate操作Oarcle中Clob、Blob字段小结

    - 包含在`bigstring_oracle_src`可能有示例代码,展示了如何在Java中创建Clob和Blob对象,以及如何通过Hibernate进行插入、更新和查询操作。 总之,理解并熟练掌握Hibernate对Oracle中的Clob和Blob字段的操作,是...

    hibernate保存blob,clob对象

    在上面的代码中,`SerialBlob`是JDBC API提供的一个类,用于将字节数组转化为Blob对象,而`StringClob`可能需要特定的库来实现,如Apache Commons Lang的`StringUtils.toClob()`方法。 在检索大型对象时,Hibernate...

    关于在Hibernate中对于Clob,Blob字段的处理方法

    在保存或更新带有Clob和Blob字段的实体时,Hibernate会自动处理这些数据的插入和更新操作。例如,当你调用`session.saveOrUpdate(entity)`或`entityManager.persist(entity)`时,Hibernate会将Clob和Blob的内容正确...

    Hibernate对Blob,Clob的操作

    在Java Web开发中,...本文将详细介绍如何在Hibernate中操作Blob和Clob字段,实现数据的存储与读取。 首先,我们需要在Hibernate映射文件(.hbm.xml)中定义Blob和Clob字段。对于Blob,可以这样声明: ```xml ...

    使用hibernate对oracle读取blob

    本文将详细介绍如何使用Hibernate和JDBC读取和存储Oracle数据库中的Blob对象。 ### 1. Hibernate Blob操作 在Hibernate中,Blob对象通常与Java的`java.sql.Blob`接口相对应。在实体类中,你可以定义一个Blob类型的...

    hibernate Blob、Clob字段的映射的例子

    hibernate Blob、Clob字段的映射的例子.数据库mysql,数据库放在文件夹里面,例子的说明文章在我的csdn blog: http://blog.csdn.net/zhengcandan

    解析使用jdbc,hibernate处理clob/blob字段的详解

    在Java的数据库操作中,`CLOB`和`BLOB`是用于存储大对象(Large Object)的数据类型,分别用于存储字符数据和二进制数据。这篇文章主要讲解了如何使用`JDBC`和`Hibernate`这两种不同的方式来处理`CLOB`和`BLOB`字段...

    关于Clob类型在Hibernate中 的应用小结

    在这种模式下,开发者需要直接操作Clob对象,通过PreparedStatement的setClob方法设置Clob值,通过ResultSet的getClob方法获取Clob值。这种方式直接与JDBC API交互,相对繁琐,且不易于管理。 2. **以String方式...

    spring+hibernate 解决大字段(clob)

    ### Spring与Hibernate处理大字段(CLOB/BLOB) 在企业级应用开发中,经常会遇到需要存储大量文本或二进制数据的情况,这时就需要用到数据库的大字段类型如CLOB(Character Large Object)和BLOB(Binary Large ...

    java中(注解符)处理Clob(blob)类型

    Java 中处理 Clob 和 Blob 类型的注解配置 Java 中处理 Clob 和 Blob 类型的注解配置是一种常见的处理大规模数据的方法。Clob(Character Large OBject)类型和 Blob(Binary Large OBject)类型是数据库中两种常用...

    spring+hibernate操作oracle的clob字段

    Spring和Hibernate框架结合使用可以有效地进行CLOB字段的操作。以下是实现这一功能的关键步骤和注意事项: 1. **配置SessionFactory** 在Spring配置文件中,你需要创建一个`SessionFactory` bean,同时指定一个`...

    详解jdbc实现对CLOB和BLOB数据类型的操作

    JDBC实现对CLOB和BLOB数据类型的操作 在数据库中,存在两种类型的数据:CLOB(Character Large OBject)和BLOB(Binary Large OBject),它们用于存储大型数据,如文本、图片、音频、视频等。对CLOB和BLOB数据类型...

    Struts2 Hibernate存取Oracle数据库中的BLOB数据.pdf

    通过Struts2与Hibernate框架的结合,开发者可以构建稳定高效的Web应用,特别是在涉及到需要存储和展示二进制大对象(BLOB)数据的场景中,这种集成方案能够充分发挥各自框架的优势,简化数据库操作,提升开发效率和...

    hibernate动态映射表处理oracle的clob类型

    - 使用Blob/Clob接口:直接操作Clob接口进行读写,而不是将其转换为字符串或其他数据类型,以减少转换开销。 通过以上内容,你应该对在Hibernate中动态映射Oracle 10g的CLOB类型有了深入理解,这将帮助你在实际...

    使用Jdbc4操作Blob,Clob

    这篇博客“使用Jdbc4操作Blob,Clob”将深入讲解如何利用JDBC4 API来处理Blob和Clob对象。 Blob通常用于存储二进制数据,如图片、音频或视频文件,而Clob则用于存储大量文本数据,如长篇的文本或XML文档。在JDBC4中...

Global site tag (gtag.js) - Google Analytics