此前在使用中将CLOB类型的数据转化为可用String类型接受的属性的方法是to_char(......),但在其使用中发现,当其长度超过4000时就会抛出异常( Cause: java.sql.SQLException: ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion)
其实本身这么转换就存在问题,因为CLOB的长度最大可为4G,如此转换肯定会存在问题,以下是正确的转换方式:
在相应的informationRelease.xml文件如此表示
<resultMap id="getInformationByIdResultMap" class="com.foundersc.crmweb.entity.information.InformationTo"> <result property="id" column="id"/> <result property="title" column="title"/> <result property="mediaSource" column="mediaSource"/> <result property="publishDate" column="publishDate"/> <result property="publishUserName" column="publishUserName"/> <result property="createDt" column="createDt"/> <result property="keyword" column="keyword"/> <result property="cascadeType" column="cascadeType"/> <result property="industrySort" column="industrySort"/> <result property="relationCode" column="relationCode"/> <result property="isRelease" column="isRelease"/> <result property="publishUserId" column="publishUserId"/> <result property="sendGroupType" column="sendGroupType"/> <result property="readedCount" column="readedCount"/> <result property="message" column="message"/> <result property="content" column="content" jdbcType="CLOB" javaType = "java.lang.String" typeHandler="com.foundersc.crmweb.util.OracleClobTypeHandlerCallback"/> </resultMap>
<select id="information.getInformationById" resultMap="getInformationByIdResultMap" parameterClass="java.lang.String"> SELECT distinct info.information_id As id, info.title AS title, info.media_source AS mediaSource, info.publish_date AS publishDate, userT.userName AS publishUserName, info.create_dt AS createDt, infoContent.content AS content, info.keyword AS keyword, info.cascade_type AS cascadeType, info.industry_sort AS industrySort, info.relation_code AS relationCode, info.is_release AS isRelease, info.publish_userId AS publishUserId, info.send_group_type AS sendGroupType, info.readed_count AS readedCount, info.message AS message FROM crm.crm_t_information info left join crm.crm_t_information_content infoContent on infoContent.information_id = info.information_id left join kf.au_t_user userT on userT.user_id = info.create_by WHERE info.information_id = #informationId# </select>
?
?其中红色字体标示的地方才是咱们真正关心的,其中typeHandler的值即为咱们写的转换CLOB类型为String类型的java代码的路径,其java代码如下:
package com.foundersc.crmweb.util;import java.sql.SQLException;import oracle.sql.CLOB;import com.ibatis.sqlmap.client.extensions.ParameterSetter;import com.ibatis.sqlmap.client.extensions.ResultGetter;import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;public class OracleClobTypeHandlerCallback implements TypeHandlerCallback { //获取时将CLOB类型的值转换为我们需要的,此处转换为了Object public Object getResult(ResultGetter getter) throws SQLException { CLOB clob = (CLOB) getter.getClob(); return (clob == null || clob.length() == 0 )? "" :clob.getSubString((long)1, (int)clob.length()); } //用CLOB类型的变量接受从数据库中读取的值 @SuppressWarnings("deprecation") public void setParameter(ParameterSetter setter, Object obj) throws SQLException { CLOB clob = CLOB.empty_lob(); clob.setString(1, (String)obj); setter.setClob(clob); } public Object valueOf(String arg0) { // TODO Auto-generated method stub return null; }}
?
备注:在查询的sql语句中不能含有distinct,至于原因我也不太清楚。