oracle的clob赋值_仅可以为插入 LONG 列的 LONG 值赋值 CLOB的解决方案

最近在做一个项目,原先是用Mysql数据库开发的,现在因客户要求,迁移到oracle。

开发的环境是,wsi(webwork+spring+ibaits).

数据库的字符集是UTF-8.

迁移过程中,碰到了这样一个问题,向一个表中执行update和insert操作时,类型为CLOB列的就出现异常

异常为:

仅可以为插入 LONG 列的 LONG 值赋值 CLOB

............

当时上网查了,有很多人也碰到了相同的问题,总体而言有两种解决方式,

第一种是驱动版本过低。

第二种是修改hibernate的配置文件,当时,前提是你开发的持久层必须是hibernate。

我从oracle官方网站下了一个最新的JDBC驱动(通过附件上传了),运行还是报哪个错误。没有效果。

而第二种方法,对于我而言,是肯定行不通的。

网上有部分人说,值长度在2000-4000之间会出现异常,

可是,我的不同,

我的是值的长度在1000-2000之间会出现异常,稍短或长都没问题。

在这里说明一下,肯定不会是因为长度限制的问题,因为CLOB在ORACLE里面,所输入的可达4G。

对于LONG,这个类型我没用过,在ORACLE里面也不建议用。是一个已经被废弃了的类型。

最后我的解决方法是,在视图层,对所输入的进行判断,把少了的用空格不上,在jsp中,四个空格等于一个字符的长度。

让其长度超过2000即可,但是,这种方法对于紧急情况可能还不错,而效率上就不说了。

还有,就是说,如果你的长度不会超过2000,就建议用varchar2,但是需要注意的是数据库字符集应该是UTF-8的,对于UTF-8或欧洲的某些字符集,oracle在存储时,对于一个字符需要2个或3个字节的存储空间,虽然表定义中varchar2(4000),但是其实该字段的data_length为其2倍或3倍长。

在这里,也顺便把在网上看到的,关于hibernate修改配置的方法,粘贴出来.

Hibernate實體對象中的数据成员类型为String,映射的数据库字段类型为org.springframework.orm.hibernate.support.ClobStringType 。實例如下:

@SuppressWarnings( " serial " )

@Entity

@Table(name = " GUIDE " )

// @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class Guide {

@Type(type = " org.springframework.orm.hibernate3.support.ClobStringType " )

private String content; // 内容

// get & set

}

如果使用Spring的这个Clob类型就需要在applicationContext.xml中的sessionFactory bean里注入oracleLobHandler bean。下面給出Oracle數據庫的LobHandler配置

< bean id ="oracleLobHandler"

class ="org.springframework.jdbc.support.lob.OracleLobHandler"

lazy-init ="true" >

< property name ="nativeJdbcExtractor" ref ="nativeJdbcExtractor" />

bean >

< bean id ="nativeJdbcExtractor" class ="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"

lazy-init ="true" />

< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >

< property name ="dataSource" ref ="dataSource" />

< property name ="configLocation" value ="classpath:hibernate/hibernate.cfg.xml" />

< property name ="hibernateProperties" >

< value >

value >

property >

< property name ="lobHandler" ref ="oracleLobHandler" />

bean >

LobHandler 需要访问本地 JDBC 对象,这一任务委托给 NativeJdbcExtractor Bean 来完成,NativeJdbcExtractor是一個本地JDBC對象抽取器,因此我們为 LobHandler 注入了一个 nativeJdbcExtractor。最后,我们把 lobHandler Bean 注入到需要进行 LOB 数据访问操作的sessionFactory Bean中或者直接注入到dao Bean中去。

大家可能已经注意到 nativeJdbcExtractor 和 oracleLobHandler Bean 都设置为 lazy-init="true",这是因为 nativeJdbcExtractor 需要通过运行期的反射机制获取底层的JDBC 对象,所以需要避免在 Spring 容器启动时就实例化这两个Bean。

如果底層數據庫是 DB2、SQL Server、MySQL 等非 Oracle 的其它數據庫,则只要简单配置一个 DefaultLobHandler 就可以了,如下所示:

< bean id ="defaultLobHandler"

class ="org.springframework.jdbc.support.lob.DefaultLobHandler"

lazy-init ="true" />

< bean id ="testDao" class ="com.test.dao.jdbc.TestJdbcDao" >

< property name ="lobHandler" ref =" defaultLobHandler" />

< property name ="jdbcTemplate" ref ="jdbcTemplate" />

bean >

DefaultLobHandler 只是简单地代理标准 JDBC 的 PreparedStatement 和 ResultSet 对象,由于并不需要访问数据库驱动本地的 JDBC 对象,所以它不需要 NativeJdbcExtractor 的帮助。

希望总有一张方法能帮你解决掉麻烦的ORA-01461。

如果,哪位有更好的解决方法,就麻烦分享一下了。

下载次数: 3

分享到:

2011-04-22 14:31

浏览 2412

分类:数据库

评论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值