`

Jdbctemplate操作Clob字段

 
阅读更多

       最近开发需求中要求大数据的入库操作,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&quot;</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;
    }
1
3
分享到:
评论

相关推荐

    利用spring的jdbcTemplate处理blob、clob

    spring 中对大数据的处理,包括clob,blob的数据。比之jdbc下简便很多。

    JdbcTemplate操作总结

    《JdbcTemplate操作总结》 在Java的Spring框架中,JdbcTemplate是用于简化数据库操作的核心组件。它提供了一种模板方法模式,将SQL语句的执行和结果处理进行了封装,使得数据库访问更加简单、安全。本篇文章将围绕...

    spring2通过jdbc的方式读取、更新数据库的clob或者blob类型的数据

    2. **使用JdbcTemplate操作CLOB和BLOB**: - 插入:可以使用PreparedStatement的`setClob()`方法设置CLOB值,`setBlob()`方法设置BLOB值,然后调用JdbcTemplate的`update()`方法执行SQL。 - 查询:同样使用...

    04JdbcTemplate操作数据库.md

    04JdbcTemplate操作数据库.md

    JdbcTemplate操作数据库实现添加功能

    在Java开发中,Spring框架提供了一个强大的数据访问抽象层,其中`JdbcTemplate`是用于简化数据库操作的重要组件。本文将详细讲解如何利用`JdbcTemplate`实现数据库的添加(INSERT)功能,以及它在实际开发中的应用和...

    使用JdbcTemplate操作数据库.zip

    在Spring Boot框架中,JdbcTemplate是一个非常重要的组件,它提供了简化数据库操作的API,使得开发者可以更加方便地执行SQL语句。本项目旨在利用JdbcTemplate进行数据库操作,从而实现一些常见的数据库交互功能。 ...

    springboot-jpa加上jdbctemple

    5. 使用JdbcTemplate:在Service或Repository中注入JdbcTemplate实例,编写SQL操作代码。 文件列表中提到的"model"可能是指项目的模型层,包含实体类和相关领域对象。这些类通常会用到JPA的注解,如`@Entity`、`@...

    打印JdbcTemplate执行sql

    其中,`JdbcTemplate`是Spring JDBC模块的核心组件,为数据库操作提供了简单、灵活的API。这篇博客文章的标题"打印JdbcTemplate执行sql"主要涉及如何在使用`JdbcTemplate`时,追踪并打印出执行的SQL语句,这对于调试...

    java基于jdbctemplate数据持久层操作封装

    Java中的JdbcTemplate是Spring框架提供的一种用于简化JDBC(Java Database Connectivity)操作的工具,它在数据持久层操作中扮演着重要角色。JdbcTemplate通过消除大量重复的JDBC样板代码,提高了代码的可读性和可...

    SpringBoot操作多数据源(JPA+JdbcTemplate)

    2. **JdbcTemplate操作**:你可以通过`@Autowired`注入特定数据源的`JdbcTemplate`实例,然后调用其方法执行SQL。例如: ```java @Autowired private JdbcTemplate primaryJdbcTemplate; @Autowired private ...

    Spring JdbcTemplate 常用方法整理

    Spring的JdbcTemplate是Spring框架中用于简化数据库操作的工具类,它是基于JDBC但又抽象出了一层,避免了直接与数据库驱动API交互,从而提高了代码的可读性和可维护性。本文将深入探讨Spring JdbcTemplate的常用方法...

    Spring--JdbcTemplate.pdf

    标题中提到的"JdbcTemplate"是Spring框架中提供的一个用于简化数据库操作的JDBC抽象库。它是对Java标准数据库编程接口JDBC的一种封装,旨在简化JDBC编程,减少样板代码,使得开发者在使用Spring框架时能够更便捷地对...

    SpringJdbcTemplate封装工具类

    在描述中提到的“规范model格式接口”,可能是指创建一套标准的数据访问接口,这些接口定义了CRUD(Create、Read、Update、Delete)操作,并由SpringJdbcTemplate实现具体的数据库交互逻辑。这样做的好处是解耦了...

    spring-jdbcTemplate实例工程

    在这个实例工程中,我们将深入探讨Spring JdbcTemplate的基本使用、优势以及常见操作。 一、Spring JdbcTemplate简介 Spring JdbcTemplate的出现是为了弥补原生JDBC在编码上的繁琐,它通过模板方法模式,将SQL执行...

    JdbcTemplate的事务控制.docx

    然而,单纯使用`JdbcTemplate`进行数据库操作时,并不能自动管理事务,因此我们需要了解如何通过`JdbcTemplate`结合Spring框架来实现事务控制。 #### 二、原生 JDBC 的事务控制 在没有使用任何框架的情况下,我们...

    简单易行:Spring中操作LOB字段案例

    总结起来,本文通过一个简单的Spring案例展示了如何操作LOB字段,包括创建DAO方法,使用`JdbcTemplate`进行数据库操作,以及在Web应用中处理文件上传。同时,我们也了解了如何配置Spring的`JdbcTemplate`和数据库...

    spring的jdbctemplate的crud的基类dao

    这是通过`@Resource`注解实现的,它告诉Spring容器将名称为`jdbcTemplate`的bean注入到这个字段中。 在`BaseDaoImpl` 类中,`find` 方法的实现使用了`JdbcTemplate`的`query`方法。这个方法可以接受SQL语句、参数...

    spring自带的jdbcTemplate查询、插入预编译使用

    在Spring框架中,`jdbcTemplate`是一个非常重要的组件,它为数据库操作提供了便捷且安全的API,降低了SQL注入的风险。本篇文章将详细讲解`jdbcTemplate`的预编译使用,以及如何通过回调方法进行定制化的数据处理。 ...

    简单介绍如何使用Spring Boot使用JdbcTemplate与MySQL进行数据库操作

    在本文中,我们将深入探讨如何使用Spring Boot集成JdbcTemplate与MySQL数据库进行数据操作。Spring Boot以其简化配置和快速启动的特点,已经成为Java开发者的首选框架。而JdbcTemplate是Spring框架的一部分,它提供...

Global site tag (gtag.js) - Google Analytics