2012-09-07 16 views
0

我有用戶上傳CSV文件,我需要存儲爲CLOB,在Oracle表。爲CLOB在Oracle使用JDBC節省的InputStream

所以我有這樣的代碼:

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(); 
    } 
}); 

另外,我使用的方法和的setClob PreparedStatement的的調用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:本TABL Ë真的有CLOB字段:

P_FILE CLOB NOT NULL, 

UPD: 我還沒有真正嘗試了Oracle實現的方法。它的工作原理,唯一的問題是oracle驅動程序並不是將所有的方法與PreparedStatement接口中的方法進行比較。來看看可能的可用方法的類是OraclePreparedStatement ...

+0

你嘗試過的setCharacterStream? http://stackoverflow.com/a/5067581/706695 – HRgiger

+0

@HRgiger是的,我正在使用setCharacterStream - 這是我的問題實際上是什麼。只有你所鏈接的回答差異 - 我用不StringReader,但InputStreamReader的。我能讀一切爲一個字符串,然後創建一個StreamReader(它的實際工作!) - 但它只是一個混亂的解決方案 – javagirl

+0

林不知道如果我理解正確,但clob是文本輸入。如果你想要字節輸入使用blob。如果輸入流實際上是文本的,可以嘗試將它讀入一個字符串並將其寫入數據庫。你可以使setString與clob btw一起工作。 –

回答

1

AbstractMethodError javadoc

當應用程序試圖調用一個抽象方法拋出。通常, 這個錯誤被編譯器捕獲; 如果某些類的定義,因爲 當前正在執行的方法,最後編譯了不相容改變只能發生在運行這個錯誤 時間。

檢查,以確保所有的類都是電流。我會做一個乾淨的和重建你的整個項目。此外,請確保您的編譯時和運行時類路徑是相同的(就庫版本等而言)

+0

@GriffeyDoc一切編譯成功,但是當你有一個Spring應用程序,通過ApplicationContext中加載豆,而當像實際的連接對象下一堆包裝紙隱藏 - 它變得複雜。 DelegatingPreparedStatement這種情況就是這種情況 – javagirl

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;