Java 使用jdbc在oracle中将InputStream保存为clob

Java 使用jdbc在oracle中将InputStream保存为clob,java,oracle,jdbc,clob,apache-commons-dbcp,Java,Oracle,Jdbc,Clob,Apache Commons Dbcp,我有一个由用户上传的csv文件,我需要将其作为Clob存储在oracle表中 因此,我有以下代码: MultipartHttpServletRequest mr = (MultipartHttpServletRequest) ctx.getRequest(); final MultipartFile f = mr.getFile("datafile"); final InputStream is = f.getInputStream(); ... jdbc.ge

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

因此,我有以下代码:

 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();
   }
});
底层的InputStream是ByteArrayInputStream(如果这有什么区别的话)

PS:表中确实有CLOB字段:

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

来自:

当应用程序尝试调用抽象方法时引发。正常地 此错误被编译器捕获此错误只能在运行时发生 如果某个类的定义自 当前执行的方法是上次编译的

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

通过使用。请参见项目中的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();
        }
    }
}

你试过setcharacterstream吗@HRgiger是的,我使用的是setCharacterStream——这就是我的问题中的实际内容。和你们链接的答案唯一不同的是,我使用的不是StringReader,而是InputStreamReader。。我可以将所有内容读取到一个字符串,然后创建一个StreamReader(它实际上可以工作!)-但这只是一个混乱的解决方案我不确定我是否理解正确,但clob用于文本输入。如果需要字节输入,请使用blob。如果输入流实际上是文本的,可以尝试将其读入字符串并将其写入数据库。顺便说一句,你可以让setString与clob一起工作。@GriffeyDoc一切都能成功编译,但是当你有一个spring应用程序,通过ApplicationContext加载了一个bean,并且当连接等实际对象隐藏在一堆包装下时,它会变得复杂。DelegatingPreparedStatement的这个案例就是其中之一
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();
        }
    }
}
@ImplicitType(translator=WidgetTanslator1.class)
Widget widget;