这几天由于项目需要,处理oracle Clob类型的数据,由于使用的是hibernate,网络上找的文章有太多是讲的hibernate1.x时代的了,通常都是一个强制转化为oracle.sql.CLOB /BLOB,结果当然是不行,因为hibernate2,3封装了一层,返回的实际上是hibernate.SerializableClob... ,还看了一些hibernate UserType的使用,但总有局限性,比如版本要求,服务器要求。。。
现总结对比如下几种操作方法 :
大的范围来讲有两种驱动:oci,thin方式,oci本身支持>4k字节的传输,处理相对比较方便,但是要求连接数据库的一端必须安装oracle客户端环境(配置本地NET服务名
url: jdbc:oracle:oci8:@oracle )
如果想传输大于4K字节的数据,请使用OCI驱动,用HIBERNATE如果不获得ORACLE的CLOB实现,无法传输超过4K字节的数据;
方法一。
Hibernate 映射文件:
name="clob_content"
type="java.sql.Clob"
update="true"
insert="true"
column="content"
not-null="false"/>
JAVABEAN: private java.sql.Clob clob_content;
DaoImp:
public void saveItem(Item item) {
String str = item.getContent();
item.setClob_content(Hibernate.createClob(str));//这里构造了该clob,并设置到object中去
getHibernateTemplate().saveOrUpdate(item);
getHibernateTemplate().flush();
}
public Item getItem(Long itemId) {
Item item = (Item) getHibernateTemplate().get(Item.class, itemId);
if(item!=null){
java.sql.Clob clob = item.getClob_content();
Strint tempStr = clob.getSubString(1, (int) clob.length());
item.setContent(tempStr);
}
return item;
}
方法二:使用hibernate的用户类型 (参考: http://www.hibernate.org/76.html)
(1)Hibernate 映射文件:
name="clob_content"
type="StringClobType"
column="content"
/>
(2)javabean: private String clob_content;
(3)
/* StringClobType类源码*/
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Clob;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.usertype.*;
public class StringClobType implements UserType {
public int[] sqlTypes() {
return new int[] { Types.CLOB };
}
public Class returnedClass() {
return String.class;
}
public boolean equals(Object x, Object y) {
return (x == y) || (x != null && y != null && (x.equals(y)));
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Reader reader = rs.getCharacterStream(names[0]);
if (reader == null)
return null;
StringBuffer sb = new StringBuffer();
try {
char[] charbuf = new char[4096];
for (int i = reader.read(charbuf); i > 0; i = reader.read(charbuf)) {
sb.append(charbuf, 0, i);
}
} catch (IOException e) {
throw new SQLException(e.getMessage());
}
return sb.toString();
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
if (value != null) {
StringReader r = new StringReader((String) value);
st.setCharacterStream(index, r, ((String) value).length());
} else {
st.setNull(index, sqlTypes()[0]);
}
}
public Object deepCopy(Object value) {
if (value == null)
return null;
return new String((String) value);
}
public boolean isMutable() {
return false;
}
/*
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
public int hashCode(Object arg0) throws HibernateException {
// TODO 自动生成方法存根
return 0;
}
/*
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
public Serializable disassemble(Object arg0) throws HibernateException {
// TODO 自动生成方法存根
return null;
}
/*
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
*/
public Object assemble(Serializable arg0, Object arg1) throws HibernateException {
// TODO 自动生成方法存根
return null;
}
/*
* @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
*/
public Object replace(Object arg0, Object arg1, Object arg2) throws HibernateException {
// TODO 自动生成方法存根
return null;
}
}
DaoImp:
与其他字段一样的处理,get/set就可以了
/* End: StringClobType类源码*/
注意:以上两种方法,在采用oracle thin方式连接的情况下 经我测试都不能传输超过4K字节
采用oci连接方式(jdbc:oracle:oci8:@orclsid) 则可以,但必须设置 hibernate的propertie
0 (注意此设置有可能导致旧的代码有批量更新的问题,我的解决办法是其他代码采用一个新的数据源)
/*
oracle10g JDBC驱动可以处理clob 类型,直接采用String 就好了,但采用hiberbate ,我不知道如何设置他的 特性:
SetBigStringTryClob 为 true
http://www.javaworld.com.tw/jute/post/view?bid=11&id=80295&sty=1&tpg=1&age=0
(楼主说可以,但我测试没有成功)
//oracle 官方说明及例子
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/lob/LobToSP.html
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/clob10g/handlingclobsinoraclejdbc10g.html
*/