java 批量更新 clob_spring+hibernate 处理oracle clob (编辑中)

这几天由于项目需要,处理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  为  truehttp://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

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值