java 关于操作oracle的clob类型

在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了。因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种类型的字段,很灵活,适用于数据量非常大的业务领域(如图象、档案等)。而LONG、LONG RAW等类型的字段,虽然存储容量也不小(可达2GB),但由于一个表中只能有一个这样类型的字段的限制,现在已很少使用了。

Oracle中若以字符串的形式写入数据到Clob字段中,默认的长度为4000,最大可存储4G。

直接将字符串写入Clob字段中,则最大可写4000个字节;若要写入大的字符数据,可以将字符数据以二进制流的形式写入。

网上有人贴出的clobsetCharacterStream()写入方法,可以运行,但是无法突破字符数限制,字符数超出就直接为null,故果断抛弃。

Reader clobReader = new StringReader(MyText); // 转成流形式
pstmt.setCharacterStream(3, clobReader, MyText.getBytes("GBK").length);


正确方法如下:

写入的时候有三部,第一先插入一个空的empty_clob(),然后获得这个cursor,然后再修改,这要牵涉到IO流的操作。。。  

Java代码   收藏代码
  1. package com.cs.utils;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.io.Reader;  
  6. import java.sql.Connection;  
  7. import java.sql.DriverManager;  
  8. import java.sql.PreparedStatement;  
  9. import java.sql.ResultSet;  
  10. import java.sql.SQLException;  
  11.   
  12. import oracle.sql.CLOB;  
  13.   
  14. /** 
  15.  *  
  16.  * @author c.s 
  17.  * 
  18.  */  
  19. public class ClobTest {  
  20.       
  21.     private static Connection conn=null;  
  22.       
  23.     private static PreparedStatement ps=null;  
  24.       
  25.     private static ResultSet rst=null;  
  26.       
  27.     static{  
  28.         try {  
  29.             Class.forName("oracle.jdbc.driver.OracleDriver");  
  30.             conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:WMG""hibernate","hibernate");  
  31.         } catch (ClassNotFoundException e) {  
  32.             e.printStackTrace();  
  33.         } catch (SQLException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.     }  
  37.       
  38.     /** 
  39.      * 插入Clob数据 
  40.      * @param strClob 
  41.      * @return 
  42.      */  
  43.     public boolean inserClob(String userid, String strClob){  
  44.         boolean suc=false;  
  45.         CLOB clob=null;
  46.   
  47.         //————————————第一步:插入一个空的Clob对象,这是一个Cursor——————————————————  
  48.         String sql="INSERT into test_clob(userid,clob_test) VALUES(?,empty_clob())";  
  49.         try {  
  50.             //禁用自动提交事务  
  51.             conn.setAutoCommit(false);  
  52.             ps=conn.prepareStatement(sql);  
  53.             ps.setString(1, userid);  
  54.             ps.executeUpdate();  
  55.             ps.close();  
  56.               
  57.             //————————————————第二步:查询并获得这个cursor,并且加锁————————————————  
  58.             sql="SELECT clob_test FROM test_clob WHERE userid=? for update";  
  59.             ps=conn.prepareStatement(sql);  
  60.             ps.setString(1, userid);  
  61.             rst=ps.executeQuery();  
  62.             if(rst.next()){  
  63.                 clob=(CLOB)rst.getClob(1);  
  64.             }  
  65.             //获得clob对象的输出流  
  66.             PrintWriter pw=new PrintWriter(clob.getCharacterOutputStream());  
  67.             pw.write(strClob);  
  68.             //一定要flush(),否则不会将String对象写入到Clob当中去。。。  
  69.             pw.flush();  
  70.             ps.close();  
  71.               
  72.             //——————————————————第三步:更新clob对象————————————————————  
  73.             sql="UPDATE test_clob set clob_test =? where userid=?";  
  74.             ps=conn.prepareStatement(sql);  
  75.             ps.setClob(1, clob);  
  76.             ps.setString(2, userid);  
  77.             ps.executeUpdate();  
  78.             ps.close();  
  79.             conn.commit();  
  80.             pw.close();  
  81.         } catch (SQLException e) {  
  82.             e.printStackTrace();  
  83.         }  
  84.           
  85.         return suc;  
  86.     }  
  87.     /** 
  88.      * 输出Clob对象 
  89.      * @param userid 
  90.      */  
  91.     public String readClob(String userid){  
  92.         String test_clob="";  
  93.         CLOB clob=null;  
  94.         StringBuffer sb=new StringBuffer();  
  95.         String sql="SELECT * FROM test_clob WHERE userid='"+userid+"'";  
  96.         try {  
  97.             ps=conn.prepareStatement(sql);  
  98.             rst=ps.executeQuery();  
  99.             if(rst.next()){  
  100.                 clob=(CLOB)rst.getClob(2);  
  101.             }  
  102.             Reader reader=clob.getCharacterStream();  
  103.             char[] buffer=new char[1024];  
  104.             int length=0;  
  105.             while((length=reader.read(buffer))!=-1){  
  106.                 sb.append(buffer, 0, length);  
  107.             }  
  108.         } catch (SQLException e) {  
  109.             e.printStackTrace();  
  110.         } catch (IOException e) {  
  111.             e.printStackTrace();  
  112.         }  
  113.         test_clob=sb.toString();  
  114.         return test_clob;  
  115.     }  
  116.     public static void main(String[] args){  
  117.         new ClobTest().inserClob("4","我是Clob,出来了哈哈哈");  
  118.         String test=new ClobTest().readClob("4");  
  119.         System.out.println(test);  
  120.     }  
  121. }  
具体来说,对于一般数据操作有insert、updata两种:
(1)updata操作,可以获取现成的id,找到指定clob字段更新。只需要做第二、三步。
(2)insert操作,因是新插入的数据,故id未定(同时可能有很多插入操作)第一步可以与其他字段一起insert,但是第二、三步,如何取得生成的id呢?通过查询序列器,会不会得不到当前这条数据的id?
辛亏数据字段里有一个是时间戳ctime,我就用ctime  去select  id了。暂且将就着吧!望高人提供更正确的方法。
  1. Select TO_CHAR(SEQ_ID.nextval) ID FROM DUAL        

你可能感兴趣的:(java 关于操作oracle的clob类型)