使用jdbc将InputStream保存为oracle中的clob

时间:2012-09-07 14:49:33

标签: java oracle jdbc clob apache-commons-dbcp

我有一个用户上传的csv文件,我需要在oracle表中存储为Clob。

因此我有这段代码:

 MultipartHttpServletRequest mr = (MultipartHttpServletRequest) ctx.getRequest();
    final MultipartFile f = mr.getFile("datafile");
    final InputStream is = f.getInputStream();
     ...
   jdbc.getJdbcOperations().execute(sql, new PreparedStatementCallback<Integer>() {
     public Integer doInPreparedStatement(final PreparedStatement psInsert) throws SQLException,
                            DataAccessException {
     ...
    psInsert.setCharacterStream(1, new InputStreamReader(is));
    psInsert.executeUpdate();
   }
});

另外,我尝试过使用PreparedStatement的setClob和setAsciiStream方法,以及我尝试this方法(设置文件的大小),但结果是一样的 -

java.lang.AbstractMethodError
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338)
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338)
    org.apache.commons.dbcp.DelegatingPreparedStatement.setAsciiStream(DelegatingPreparedStatement.java:338)

底层的InputStream是ByteArrayInputStream(如果这可能有任何区别)

PS:该表确实有CLOB字段:

P_FILE CLOB NOT NULL,

UPD: 我还没有尝试过Oracle实现的方法。它工作,唯一的问题是oracle驱动程序实现的不是所有方法与PreparedStatement接口中的方法相比。查看可能的可用方法的类是OraclePreparedStatement ...

2 个答案:

答案 0 :(得分:1)

来自AbstractMethodError javadoc

  

当应用程序尝试调用抽象方法时抛出。一般,   编译器捕获此错误; 此错误只能在运行时发生   时间,如果某个类的定义自那以后不一致改变了   当前正在执行的方法是最后编译的

检查以确保所有课程都是最新的。我会干净整修你的整个项目。另外,请确保您的编译时和运行时类路径是等效的(就库版本等而言)

答案 1 :(得分:0)

Sormula可以使用TypeTranslator轻松读取/写入任何类型。请参阅项目中的org.sormula.examples.blob包。 CLOB的代码类似。

public class WidgetTanslator1 implements TypeTranslator<Widget>
{
    public void write(PreparedStatement preparedStatement, int parameterIndex, Widget parameter) throws Exception
    {
        // convert from domain object to bytes
        ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
        try (ObjectOutputStream oos = new ObjectOutputStream(bos))
        {
            oos.writeObject(parameter);

            // convert bytes to jdbc blob
            preparedStatement.setBlob(parameterIndex, new SerialBlob(bos.toByteArray()));
        }
    }


    public Widget read(ResultSet resultSet, int parameterIndex) throws Exception
    {
        // convert from jdbc blob to bytes to domain object
        Blob blob = resultSet.getBlob(parameterIndex);
        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(blob.getBytes(1, (int)blob.length()))))
        {
            return (Widget)ois.readObject();
        }
    }
}

注释CLOB字段,如下所示:

@ImplicitType(translator=WidgetTanslator1.class)
Widget widget;