spring + mybatis 存取clob

    存的時候會比較麻煩,須要使用select for update的方式更新數據,若是原來沒有這一條數據,還須要先新增,新增的時候須要將clob字段存爲oracle.sql.CLOB.empty_lob((),而後用create for update 方式查詢出來這一條數據,查詢出的clob字段須要用clob.putString方式定義,最後才能用update語句將clob字段更新到數據庫中。mybatis不能完成上面那麼複雜的操做,因此個人解決方式是直接拿spring管理的連接,而後用jdbc方式完成。須要注意的是,使用使用原始jdbc方式操做數據時,和mybatis的對數據庫的操做要分開,若是放在同一個事務裏面,很容易鎖表。java

    查詢的時候須要注意,jdbcType="CLOB" javaType="java.lang.String"。spring

 

下面附上別人的代碼sql

 

 Oracle中處理BLOB/CLOB字段的方式比較特別,因此須要特別注意下面兩點:

1. 在Oracle JDBC中採用流機制對 BLOB/CLOB 進行讀寫操做,因此要注意不能在批處理中讀寫 BLOB/CLOB字段,不然將出現
Stream type cannot be used in batching 異常。

2. Oracle BLOB/CLOB 字段自己擁有一個遊標(cursor),JDBC經過遊標對Blob/Clob字段進行操做,在Blob/Clob字段建立以前,沒法獲取其遊標句柄,會出現
Connection reset by peer: socket write error 異常。
           
數據庫

PreparedStatement ps=conn.prepareStatement("insert into PICTURE(image,resume) values(?,?)");
//經過oralce.sql.BLOB/CLOB.empty_lob()構造空Blob/Clob對象 
ps.setBlob(1, oracle.sql.BLOB.empty_lob());
ps.setClob(2, oracle.sql.CLOB.empty_lob());

ps.excuteUpdate();
ps.close();




//再次對讀出Blob/Clob句柄 
ps=conn.prepareStatement("select image,resume from PICTURE where id=? for update");
ps.setInt(1 , 100);

ResultSet rs=ps.executeQuery();
rs.next();
oracle.sql.BLOB imgBlob=(oracle.sql.BLOB)rs.getBlob(1);
oracle.sql.CLOB resClob=(oracle.sql.CLOB)rs.getClob(2);
 
//將二進制數據寫入Blob 
FileInputStream inStream=new FileInputStream("c://image.jpg");
OutputStream outStream=imgBlob.getBinaryOutputStream();
byte[] buf=new byte[10240];
int len;
while(len=inStream.read(buf)>0){
outStream.write(buf, 0 ,len);
} 
inStream.close();
outStream.cloese();


//將字符串寫入Clob 
resClob.putString(1, "this is a clob");

//再將Blob/Clob字段更新到數據庫 
ps=conn.prepareStatement("update PICTURE set image=? and resume=? where id=?");
ps.setBlob(1, imgBlob);
ps.setClob(2, resClob);
ps.setInt(3, 100 );

ps.executeUpdate();
ps.close();
相關文章
相關標籤/搜索