解决Druid设置Oracle的Clob字段时的小坑

众所周知,Oracle有很多坑, 所以才有了去IOE。

在使用Druid做数据库连接池后,其实偶尔也会碰到小坑,这就是使用开源项目所必须去填平的。【如果使用不开源的产品,那就不是坑,而是陷阱了,你都不知道怎么去填坑】

用Druid连接池,通过JDBC往Oracle数据库的Clob字段插入数据,或者更新数据时,一个问题出现了。

类似于这样:

Caused by: javacannot be cast to oracle.sql.CLOBat oracle(OraclePreparedStatement.java:7919)at _setClob(FilterChainImpl.java:2978)at _setClob(FilterAdapter.java:1178)at _setClob(FilterChainImpl.java:2975)at _setClob(FilterAdapter.java:1178)at _setClob(FilterChainImpl.java:2975)at (PreparedStatementProxyImpl.java:255)at (DruidPooledPreparedStatement.java:588)… 63 more

然后, 参考网上的文章,切换成 StringReader 以后又出现了字符串过长的问题,只好断点调试找BUG了,然后发现了一个方法:

ClobProxyImpl#getRawClob()

那么问题来了,也解决了。 代码贴出来如下所示:

package com.cncounter.util.solution.processor;import java.sql.Clob;import java.sql.PreparedStatement;import java.sql.SQLException;{ String JDBC_TYPE_CLOB = “clob”; (PreparedStatement statement, int order,String jdbcType, Object paramValue) {boolean result = false;if(null == statement || order < 1){return result;}//String value = “”;if(null != paramValue){value = paramValue.toString();}//try {if(JDBC_TYPE_CLOB.trim().equalsIgnoreCase(jdbcType)){//Clob clob = null;if(paramValue instanceof Clob){clob = (Clob)paramValue;} else {clob = statement.getConnection().createClob();// 从 1 开始clob.setString(1, value);}// 阿里巴巴的坑if(clob instanceof com.alibaba.druid.proxy.jdbc.ClobProxyImpl){com.alibaba.druid.proxy.jdbc.ClobProxyImpl impl = (com.alibaba.druid.proxy.jdbc.ClobProxyImpl)clob;clob = impl.getRawClob(); // 获取原生的这个 Clob}statement.setClob(order, clob);} else {statement.setString(order, value);}result = true;} catch (SQLException e) {throw new RuntimeException(“设置[“+jdbcType+”]类型出错!”, e);}//return result; }}

分析了下原因,,大概Druid是因为Clob有什么需要处理的,就增加了一个代理类: com.alibaba.druid.proxy.jdbc.ClobProxyImpl ; Blob就没有。 然后呢,Oracle也比较粗暴,setClob() 里面直接强转为 oracle.sql.CLOB。于是问题就出现了。

另外值得一提的是MyBatis的Clob类型有BUG,在上面的代码注释之中也提醒了,属于是 StringReader 的坑,反正谁用谁知道。 我们的处理策略是, 在 xml 之中不指定 jdbcType,由MyBatis自己判断,当成String处理就不报错,然后也就不管了。

作者: 铁锚

日期: 2015年04月05日

松树亭亭玉立的耸立在周围小草小花的中间,

解决Druid设置Oracle的Clob字段时的小坑

相关文章:

你感兴趣的文章:

标签云: