关于CLOB数据类型,网上已经有很多的解决方案,但是JDBC操作过于的复杂,Hibernate的操作稳定性不好,大部分时间可以的,有时又会报莫名的错误,经过一段时间的测试调出一套相对比较宗合的解决方案.现在帖上来和大家共享,请大家给予点意见
1.在spring的配置文件内配一下sessionFactory <bean id="sessionFactory" class="org.springframework..."> <property name="dataSource"><ref local="dataSource"/></property> <property name="mappingDirectoryLocations"> <list> <value>WEB-INF/mappings</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> ... </props> </property> <property name="lobHandler"> <ref bean="oracleLobHandler" /> </property> </bean> 再配一个 <!-- 解决CLOB --> <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor" /> <bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" > <property name="nativeJdbcExtractor"> <ref bean="nativeJdbcExtractor" /> </property> </bean>
2.将JAVABEAN里对应数据库CLOB列的属性设为String类型,在hbm.xml的映射文件中配置: <property name="content" type="org.springframework.orm.hibernate3.support.ClobStringType" update="false" insert="false" column="content" />
3.在数据访问层里加入以下代码: public void createDiscountInfo(DiscountInfo discountInfo) { getHibernateTemplate().save(discountInfo);
String content = discountInfo.getContent(); Connection conn = null; ResultSet rs=null; try {
conn =ConnDb.getConnection(); conn.setAutoCommit(false); String sql="select content from TB_DiscountInfo where DiscountInfoId='" + discountInfo.getDiscountInfoID() + "' for update"; PreparedStatement ps = conn.prepareStatement(sql); rs = ps.executeQuery(); if(rs.next()){ java.io.Writer out=((oracle.sql.CLOB)rs.getClob("content")).getCharacterOutputStream(); java.io.StringReader in=new java.io.StringReader(content); int c; char[] chars=new char[1024]; while ((c=in.read(chars))!=-1) { out.write(chars,0,c); } in.close(); out.flush(); out.close(); } conn.commit(); } catch (Exception e) { try { conn.rollback(); } catch (Exception e1) { logger.info("事务回滚错误"); } e.printStackTrace(); } finally { try { ConnDb.freeConnection(conn); } catch (Exception e1) { logger.info("关闭连错误"); }
}*/ } 通过hibernate进行简单的保存操作,然后通过JDBC对CLOB字段进行更新操作,读取数据时用hibernate读取,不用做特别的处理,就可以象用字符串一样对CLOB进行读取,更新操作和保存操作相似就不说了
4.这一点比较得要,要将数据库里CLOB字段的默认值设为"",千万不可以让数据库此字段为NULL,因为在更新时读取CLOB字段为NULL时转换会报错,将此字段设置为 alter table tab1 modify CONTENT default EMPTY_CLOB() 还有一点要提醒大家,请大家看2,那里的insert和update的值设置都为false,就是说Hibernate都不对CLOB字段添加和修改进行操作,对CLOB的操作完全交给JDBC来做,这样做的话,CLOB的操作更加稳定.请不要将那两个属性设为true,他默认也是true,所以要显示更改
|