当我们需要操作大于4000字节的数据(字段)时,我们就需要用到oracle的CLOB数据类型。在对其进行操作时主要有以下三种方案:采用传统的jbdc方式、把clob以string方式处理和直接使用CLOB类型三种方案,下面分别作简要介绍。


方式一传统的jdbc方式
写入Blob/Clob字段和写入其它类型字段的方式非常不同,因为Blob/Clob自身有一个cursor,必须使用cursor对Blob/Club进行操作,因而在写入Blob/Club之前,必须获得cursor才能进行写入,那就需要先插入一个empty的Blob/Club,这将创建一个Blob/Club的cursor,然后再把这个empty的Blob/Club的cursor用select查询出来,这样通过两步操作,就获得了Blob/Club的cursor,可以真正的写入Blob/Club数据了。这种方式比较麻烦,读写都要增加不少工作量。有关此方法的具体实现代码请参照示例一


1、入库
(1)JDBC方式
   //通过JDBC获得数据库连接
   Class.forName("oracle.jdbc.driver.OracleDriver");
   Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testdb", "test", "test");
   con.setAutoCommit(false);
   Statement st = con.createStatement();
   //插入一个空对象empty_clob()
   st.executeUpdate("insert into TESTCLOB (ID, NAME, CLOBATTR) values (1, "thename", empty_clob())");
   //锁定数据行进行更新,注意“for update”语句
   ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1 for update");
   if (rs.next())
   {
       //得到java.sql.Clob对象后强制转换为oracle.sql.CLOB
       oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBATTR");
       Writer outStream = clob.getCharacterOutputStream();
       //data是传入的字符串,定义:String data
       char[] c = data.toCharArray();
       outStream.write(c, 0, c.length);
   }
   outStream.flush();
   outStream.close();
   con.commit();
   con.close();


2、出库
   //获得数据库连接
   Connection con = ConnectionFactory.getConnection();
   con.setAutoCommit(false);
   Statement st = con.createStatement();
   //不需要“for update”
   ResultSet rs = st.executeQuery("select CLOBATTR from TESTCLOB where ID=1");
   if (rs.next())
   {
       java.sql.Clob clob = rs.getClob("CLOBATTR");
       Reader inStream = clob.getCharacterStream();
       char[] c = new char[(int) clob.length()];
       inStream.read(c);
       //data是读出并需要返回的数据,类型是String
       data = new String(c);
       inStream.close();
   }
   inStream.close();
   con.commit();
   con.close();


方式二CLOBString方式处理
此方法主要是通过继承net.sf.hibernate.type.ImmutableType类或cirrus.hibernate.UserType类来创建一个新的类如:StringClobType,然后在相应的配置文件里面,把该字段映射为StringClobType类型,即可正常操作。此方法的优点主要体现在具体实现操作的代码较为简单,但在第一步的映射问题上,较难理解。有关此方法的具体实现代码请参照示例二。


方式三直接使用CLOB类型
第三种方法是直接使用clob类型,它主要是在实体中增加一个clobString字段,通过对该字段的读写,在DAOImpl层进行特殊处理后,转换为真正的clob类型,从而实现clob类型字段的CRUD操作。此方法主要优点体现在配置文件的映射类型上,只需要像映射其它基本类型一样,直接写上 type="clob" 就OK了。这对初次遇到这种问题的人来说入门相对容易。
1.实体类配置
在正常情况下文章实体类如下所示:
package testCLOB;
publicclass Article {
private String title;
private String content;
public String getTitle() {
returntitle;
   }
publicvoid setTitle(String title) {
this.title = title;
   }
public String getContent() {
returncontent;
   }
publicvoid setContent(String content) {
this.content = content;
   }
}
但是由于需要使用CLOB数据类型,该实体类需要进行如下变化:
package com.maskhr.jhb;
import java.sql.Clob;
publicclass Article {
private String title;
private Clob content;
private String contentString;
public String getTitle() {
returntitle;
   }
publicvoid setTitle(String title) {
this.title = title;
   }
public Clob getContent() {
returncontent;
   }
publicvoid setContent(Clob content) {
this.content = content;
   }
public String getContentString() {
returncontentString;
   }
publicvoid setContentString(String contentString) {
this.contentString = contentString;
   }
}
      其中contentString并不映射到数据库的CLOB字段,只是方便用户使用get / set 处理CLOB字段
2.hibernate映射文件
在该实体对应的映射文件里只需要增加下面一行,直接声明该字段为clob类型。
     < property name="content " column="CONTENT_CLOB" type="clob" />