posts - 40, comments - 58, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

import java.io.*;
import java.util.*;
import java.sql.*;
 
public class ClobTest {
 
    private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:ora10g";
    private static final String USER = "sc";
    private static final String PASSWORD = "sc";
    private static Connection conn = null;
    private static Statement stmt = null;

 
    /**
     * 往数据库中插入一个新的CLOB对象
     */
    public static void save(BO obj) throws Exception {
        /* 一定要设定不自动提交,否则抛出ORA-01002: 读取违反顺序 */
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);
 
        try {
            stmt = conn.createStatement();
            /* 插入一个空的CLOB对象 */
            stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ('1000', EMPTY_CLOB())");//一定要使用Oracle中的EMPTY_CLOB()函数
           
            stmt.close();//记得关掉我哦 :-)
            stmt= null;

            /* 查询此CLOB对象并锁定 */
            //stmt = conn.prepareStatement();//如果是PrepareStatement接口,一定要重新创建该对象,否则抛出ORA-01006: 赋值变量不存
           
            ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='1000' FOR UPDATE");//一定要for update锁定该记录,否则抛出ORA-22920: 未锁定含有 LOB 值的行
            while (rs.next()) {
                /* 取出此CLOB对象 */
                oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");

                /* 向CLOB对象中写入数据 */
                Writer out = clob.getCharacterOutputStream();
                //out.write(new String(obj.getEmail()));//obj.getEmail()返回byte[]类型,但是当obj.getEmail()绝对大时,执行new String(byte[])时,JVM会抛出内存溢出异常

                byte[] emails = obj.getEmail();
                ClobStreamHandler csh = new ClobStreamHandler(emails);
                String[] arrx = csh.pagedClobStream();//要解决内存溢出异常,必须把绝对大的byte[]进行分页
                if (arrx != null){
                    for (int i = 0; i < arrx.length; i++) {
                        out.write(arrx[i]);
                        out.flush();//要解决内存溢出异常,必须一页一页的flush()到数据库
                    }
                }
                else out.write("");
                out.close();
            }
            /* 正式提交 */
            conn.commit();

            /* 恢复原提交状态 */
            conn.setAutoCommit(defaultCommit);
        } catch (Exception ex) {
            /* 出错回滚 */
            conn.rollback();
            throw ex;
        } finally {相关关闭操作}
 
      
    }
 
    /**
     * 修改CLOB对象(是在原CLOB对象基础上进行覆盖式的修改)
     *
     * @param obj - 数据对象
     * @throws java.lang.Exception
     * @roseuid 3EDA04B60367
     */
    public static void modify(BO obj) throws Exception {
        /* 设定不自动提交 */
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);
 
        try {
            /* 查询CLOB对象并锁定 */
            ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='1000' FOR UPDATE");
            while (rs.next()) {
                /* 获取此CLOB对象 */
                oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");  
                
                /* 进行覆盖式修改 */
                Writer out = clob.getCharacterOutputStream();
                byte[] emails = obj.getEmail();
                ClobStreamHandler csh = new ClobStreamHandler(emails);
                String[] arrx = csh.pagedClobStream();//要解决内存溢出异常,必须把绝对大的byte[]进行分页
                if (arrx != null){
                    for (int i = 0; i < arrx.length; i++) {
                        out.write(arrx[i]);
                        out.flush();//要解决内存溢出异常,必须一页一页的flush()到数据库
                    }
                }
                else out.write("");
                out.close();
            }
            /* 正式提交 */
            conn.commit();

            /* 恢复原提交状态 */
            conn.setAutoCommit(defaultCommit);
        } catch (Exception ex) {
            /* 出错回滚 */
            conn.rollback();
            throw ex;
        } finally {相关关闭操作}
 
        /* 恢复原提交状态 */
        conn.setAutoCommit(defaultCommit);
    }
 
    /**
     * 替换CLOB对象(将原CLOB对象清除,换成一个全新的CLOB对象)
     *
     * @param obj - 数据对象
     * @throws java.lang.Exception
     * @roseuid 3EDA04BF01E1
     */
    public static void replace(BO obj) throws Exception {
        /* 设定不自动提交 */
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);
 
        try {
            /* 清空原CLOB对象 */
            stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='1000'");
            
            /* 查询CLOB对象并锁定 */
            ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='1000' FOR UPDATE");
            
            while (rs.next()) {
                /* 获取此CLOB对象 */
                oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
                /* 更新数据 */
                Writer out = clob.getCharacterOutputStream();
                byte[] emails = item.getEmail();
                ClobStreamHandler csh = new ClobStreamHandler(emails);
                String[] arrx = csh.pagedClobStream();//要解决内存溢出异常,必须把绝对大的byte[]进行分页
                if (arrx != null){
                    for (int i = 0; i < arrx.length; i++) {
                        out.write(arrx[i]);
                        out.flush();//要解决内存溢出异常,必须一页一页的flush()到数据库
                    }
                }
                else out.write("");
                out.close();
            }
            /* 正式提交 */
            conn.commit();

            /* 恢复原提交状态 */
            conn.setAutoCommit(defaultCommit);
        } catch (Exception ex) {
            /* 出错回滚 */
            conn.rollback();
            throw ex;
        } finally {相关关闭操作}
 
       
    }
 
    /**
     * 读取CLOB对象
     */
    public static byte[] read() throws Exception {
        /* 设定不自动提交 */
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);
 
        try {
            /* 查询CLOB对象 */
            ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID='1000'");
            while (rs.next()) {
                /* 获取CLOB对象 */
                oracle.sql.CLOB c= (oracle.sql.CLOB)rs.getClob("CLOBCOL");
               
                if (c != null){
                     try {
                          oracle.jdbc.driver.OracleClobInputStream is = (OracleClobInputStream) c.getAsciiStream();
                          java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
                   
                          byte[] by = new byte[1024 * 200];
                          while(is.read(by, 0, by.length) != -1){
                              baos.write(by, 0, by.length);
                              baos.flush();//把数据写入内存
                          }
                   
                          baos.close();
                          is.close();
                          return baos.toByteArray();//不会内存溢出了,呵呵. 原因是把数据写入了内存,而不是JVM的内存管理区域
                     } catch (SQLException e) {
                           //e.printStackTrace();
                     }
                }
                else return new byte[0];
                break;
            }
        } catch (Exception ex) {
            conn.rollback();
            throw ex;
        } finally {相关关闭操作}
 
        /* 恢复原提交状态 */
        conn.setAutoCommit(defaultCommit);
    }
 
    /**
     * 建立测试用表格
     * @throws Exception
     */
    public static void createTables() throws Exception {
        try {
            stmt.executeUpdate("CREATE TABLE TEST_CLOB (ID VARCHAR2(4), CLOBCOL CLOB)");
            stmt.executeUpdate("CREATE TABLE TEST_BLOB (ID VARCHAR2(4), BLOBCOL BLOB)");
        } catch (Exception ex) {
 
        }
    }
 
    public static void main(String[] args) throws Exception {
        /* 装载驱动,建立数据库连接 */
        Class.forName(DRIVER);
        conn = DriverManager.getConnection(URL, USER, PASSWORD);
        stmt = conn.createStatement();
 
        /* 建立测试表格 */
        createTables();
    }
}


    对Clob字符流进行分页的算法:
   
 1 package privy.astroqi.oracle.db.handler;
 2 
 3 /**
 4  * 
 5  * @author Astro Qi
 6  * @since  2008-07-23 00:05
 7  *
 8  */
 9 public class ClobStreamHandler {
10 
11     private static int PAGE_SIZE = 1024 * 200 * 1;
12     
13     private byte[] dataes;
14     
15     private int length;
16     
17     private int pageCount;
18     
19     public ClobStreamHandler(byte[] data){
20         if (data == null){
21             throw new java.lang.IllegalArgumentException("参数byte[]不能为空,否则无法处理接下来的操作.");
22         }
23         
24         dataes = data;
25         length = dataes.length;
26         pageCount = (length % PAGE_SIZE == 0? (length / PAGE_SIZE) : (length / PAGE_SIZE) + 1;
27         
28     }
29     
30     public String[] pagedClobStream(){
31         
32         String[] arr = new String[pageCount];
33         
34         for (int i = 1; i <= pageCount; i++) {
35             int sheYuByte = length - (PAGE_SIZE * (i - 1));
36             byte[] b = null;
37             if (sheYuByte > PAGE_SIZE){
38                 b = new byte[PAGE_SIZE];
39             } 
40             else {
41                 b = new byte[sheYuByte];
42             }
43             for (int j = 0; j < b.length; j++){
44                 b[j] = dataes[(i - 1* PAGE_SIZE + j];
45             }
46             arr[i - 1= new String(b);
47         }
48         
49         return arr;
50     }
51 }

评论

# re: JDBC ORACLE CLOB  回复  更多评论   

2008-11-03 10:56 by blskyli
非常感谢!

只有注册用户登录后才能发表评论。


网站导航: