最近开发需求中要求大数据的入库操作,LZ项目中使用的是Oracle数据库,因此选择了Clob类型存储。第一个想到的是普通的JDBC的操作,毕竟这个LZ以前处理过,但是这个程序统一使用的Spring的jdbctemplate进行的入库操作,LZ以前没接触过,就尝试研究了一番。
整体上代码难度不大,网上相关技术较多,这里简单贴下代码供参考:
xml配置(也可以直接代码中new DefaultLobHandler()):
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true"> </bean>
java代码:
String sql = "insert into TR_PROJ_INFO(INSTALLADDRESS) values(?)"; final String text="xxx"; //jt就是jdbctemplate,需要配置datasource并通过spring注入 jt.execute(sql, new AbstractLobCreatingPreparedStatementCallback(lobHandler) { @Override protected void setValues(PreparedStatement pstm, LobCreator lobCreator) throws SQLException, DataAccessException { lobCreator.setClobAsString(pstm, 1, text); } });
ok,代码写完了,LZ就拿来测试,这个时候,异常君来了。。。
org.springframework.jdbc.support.lob.DefaultLobHandler"</span></i></span></div> org.springframework.jdbc.UncategorizedSQLException: (executing PreparedStatementCallback [org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator@34e6e3]): encountered SQLException [数据大小超出此类型的最大值: 71472]; nested exception is java.sql.SQLException: 数据大小超出此类型的最大值: 71472 java.sql.SQLException: 数据大小超出此类型的最大值: 71472 at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134) at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179) at oracle.jdbc.ttc7.TTCItem.setArrayData(TTCItem.java:147) at oracle.jdbc.dbaccess.DBDataSetImpl.setBytesBindItem(DBDataSetImpl.java:2461) at oracle.jdbc.driver.OraclePreparedStatement.setItem(OraclePreparedStatement.java:1155) at oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:1572) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.logicalcobwebs.proxool.ProxyStatement.invoke(ProxyStatement.java:100) at org.logicalcobwebs.proxool.ProxyStatement.intercept(ProxyStatement.java:57) at oracle.jdbc.internal.OracleStatement$$EnhancerByProxool$$16a7118c.setString(<generated>) at org.springframework.jdbc.support.lob.DefaultLobHandler$DefaultLobCreator.setClobAsString(DefaultLobHandler.java:106) at com.blackstar.project.service.ProjectService$1.setValues(ProjectService.java:71) at org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback.doInPreparedStatement(AbstractLobCreatingPreparedStatementCallback.java:71) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:450) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:469)
LZ当时就吐血了。。。居然还有大小限制,插入的数据也就1000多个汉字,最多刚超过4000字节,大家都知道这是oracle的varchar2类型的最大值,但是我明明用了clob字段,而且据说最大支持存储4G数据量。然后LZ开始求助百度君,试了多种方案后,发现代码大同小异,异常依旧。当时LZ着急完成功能,最后试了一种折中的办法,现在看看那段代码我也是醉了,贴出来:
String sql ="INSERT INTO TR_PROJ_INFO (SEQU_ID,INSTALLADDRESS) values('"+sequId+"',empty_clob())" jt.update(sql); updateClobColumn("INSTALLADDRESS",params.get("Range"),sequId); private void updateClobColumn(String key,String value,String sequId) { if (value != null) { String updateClobSql = "UPDATE TR_PROJ_INFO set "+key+" = "+key+"||? WHERE sequ_id = ? "; while (value.length() > 500) { String temp = value.substring(0, 500); jt.update(updateClobSql, new Object[] { temp, sequId }); value = value.substring(500); } jt.update(updateClobSql, new Object[] { value, sequId }); } }
首先给clob插入空值,然后逐次插入500个字符,居然神奇的没有报错。。。
虽然最终完成了功能,但是总觉着这个方法太暴力。后来抽时间重新排查问题,LZ最后实在没办法自己搞了测试demo,一模一样的代码,然后。。。就成功了。痛苦得把jar包拎出来一个个对比,最后发现ocale驱动包居然不一样,居然是Oracle JDBC Driver version - 9.0.2.0.0,测试环境是11.2.0.1.0,泪奔,放到环境中,一切都ok了,遇到这样的问题,我也只能认栽了,最后再贴出来一段读取Clob字段的代码(根据自己需要,我的驱动包换了以后,可以直接读取出来,如果读取出来不是字符串,而是clob类,那就转化一下):
public String ClobToString(Clob clob) { String reString = ""; Reader is = null; try { is = clob.getCharacterStream(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 得到流 BufferedReader br = new BufferedReader(is); String s = null; try { s = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } StringBuffer sb = new StringBuffer(); while (s != null) { //执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING sb.append(s); try { s = br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } reString = sb.toString(); return reString; }
相关推荐
spring 中对大数据的处理,包括clob,blob的数据。比之jdbc下简便很多。
2. **使用JdbcTemplate操作CLOB和BLOB**: - 插入:可以使用PreparedStatement的`setClob()`方法设置CLOB值,`setBlob()`方法设置BLOB值,然后调用JdbcTemplate的`update()`方法执行SQL。 - 查询:同样使用...
总结起来,本文通过一个简单的Spring案例展示了如何操作LOB字段,包括创建DAO方法,使用`JdbcTemplate`进行数据库操作,以及在Web应用中处理文件上传。同时,我们也了解了如何配置Spring的`JdbcTemplate`和数据库...
以下是一个简单的示例,展示了如何使用Spring的JdbcTemplate来操作Oracle的BLOB字段: ```java @Autowired private JdbcTemplate jdbcTemplate; public void insertBlob(String tableName, Blob blobData) { ...
11.4.1. 使用JdbcTemplate进行批量操作 11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动...
在dbking中,所有的数据库数据只有五种数据类型,String、Number(BigDecimal)、Timestamp、Clob(String)、Blob(byte[]),经过反复测试后,我们会例出各种数据库数据类型到这五种类型的映射表,当然我们也有...
11.4.1. 使用JdbcTemplate进行批量操作 11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动...
- **Blob/clob映射**:处理大文本和二进制数据。 - **查询(get, load, 延迟加载)**:获取对象的不同方式及其特点。 - **Session的常用方法**:如`save()`、`update()`、`delete()`等。 - **对象在Hibernate中的...
- **JDBCTemplate**: Spring提供的简化JDBC操作的工具类。 - **Spring对Hibernate3的集成**: 通过Spring管理Hibernate的SessionFactory。 - **HibernateDaoSupport**: 提供了Hibernate Dao层的支持。 - **Hibernate...