1. 程式人生 > >JDBC 復習3 存取Oracle大數據 clob blob

JDBC 復習3 存取Oracle大數據 clob blob

其中 esc execute 自動 ram -m 復習 fin put

1 目錄結構記得導包咯 mysql oracle
技術分享圖片

2 代碼,DBUtil工具類見前面的隨筆博文


package dbex.mysql;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import dbex.DBUtil;

/**
 * 
 * @ClassName: OrcClob 
 * @Description: Oracle 字符clob大數據練習
 * @author penny
 * @date 2017年11月29日 上午10:30:37 
 *
 */
public class OrcClob {

    
    Connection conn=null;
    PreparedStatement ppst = null;
    ResultSet rs= null;
    /**
     * @throws SQLException 
     * @Title: insertClob 
     * @Description: 插入 
     * @param     
     * @throws
     */
    void insertClob() throws Exception{
        
        conn = DBUtil.getConnection();//獲取到連接對象,DBUtil 前面博文有
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);//設置不自動提交
        String path =OrcClob.class.getClassLoader().getResource("big.txt").getPath();
        path =path.replace("%20", " ");//用20%替換空格 
        
        try {
            ppst = conn.prepareStatement("insert into clob values(?,empty_clob())");
            ppst.setInt(1, 125);
            ppst.execute();
            ppst = conn.prepareStatement("select clobcol from clob where id=? for update");
            ppst.setInt(1, 125);
            rs=ppst.executeQuery();
            if(rs.next()){
                oracle.sql.CLOB clob= (oracle.sql.CLOB)rs.getClob("clobcol");
                BufferedWriter bw = new BufferedWriter(clob.getCharacterOutputStream());
                BufferedReader br = new BufferedReader(new FileReader(new File(path)));
                int len;
                while((len=br.read())!=-1){
                    System.out.println("寫入中");
                    bw.write(len);
                }
                br.close();
                bw.close();
            }
            //真正提交
            conn.commit();
            
        } catch (SQLException e) {
            e.printStackTrace();
            conn.rollback();
        }finally{
            conn.setAutoCommit(defaultCommit);
            DBUtil.closeAll(conn, ppst, rs);
        }
    }
    /**
     * @throws Exception 
     * 
     * @Title: readClob 
     * @Description: 讀取大數據
     * @param     
     * @throws
     */
    void readClob() throws Exception{
        Connection conn = DBUtil.getConnection();
        PreparedStatement ppst =null;
        ResultSet rs= null;
        boolean defaultCommit = conn.getAutoCommit();
        try {
            ppst = conn.prepareStatement("select clobcol from clob where id =?");
            ppst.setInt(1, 125);
            rs=ppst.executeQuery();
            if(rs.next()){
                oracle.sql.CLOB clob= (oracle.sql.CLOB)rs.getClob("clobcol");
                BufferedReader br = new BufferedReader(clob.getCharacterStream());
                BufferedWriter bw = new BufferedWriter(new FileWriter("2.txt"));
                int len;
                while((len=br.read())!=-1){
                    System.out.println("讀取中");
                    bw.write(len);
                }
                br.close();
                bw.close();
            }
            conn.commit();
        } catch (Exception e) {
            conn.rollback();
            throw(e);
        }finally{
            conn.setAutoCommit(defaultCommit);
            DBUtil.closeAll(conn, ppst, rs);
        }
    }
    
    public static void main(String[] args) throws Exception {
//      new OrcClob().insertClob();
        new OrcClob().readClob();
    }
}

3效果
技術分享圖片
技術分享圖片
技術分享圖片

4總結:
通過JDBC操縱Oracle數據庫的LOB字段,不外乎插入、修改、替換、讀取四種方式,掌握起來並不難。觀察上述程序對LOB類型字段的存取,我們可以看出,較之其它類型字段,有下面幾個顯著不同的特點:

  1、必須取消自動提交。

  存取操作開始前,必須用setAutoCommit(false)取消自動提交。其它類型字段則無此特殊要求。這是因為存取LOB類型字段時,通常要進行多次操作可以完成。不這樣的話,Oracle將拋出“讀取違反順序”的錯誤。

  2、插入方式不同。

  LOB數據不能象其它類型數據一樣直接插入(INSERT)。插入前必須先插入一個空的LOB對象,CLOB類型 的空對象為EMPTY_CLOB(),BLOB類型的空對象為EMPTY_BLOB()。之後通過SELECT命令查詢得到先前插入的記錄並鎖定,繼而將 空對象修改為所要插入的LOB對象。

  3、修改方式不同。

  其它類型的字段修改時,用UPDATE … SET…命令即可。而LOB類型字段,則只能用SELECT … FOR UPDATE命令將記錄查詢出來並鎖定,然後才能修改。且修改也有兩種改法:一是在原數據基礎上的修改(即覆蓋式修改),執行SELECT … FOR UPDATE後再改數據;二是替換(先將原數據清掉,再修改),先執行UPDATE命令將LOB字段之值設為空的LOB對象,然後進行第一種改法。建議使 用替換的方法,以實現與其它字段UPDATE操作後一樣的效果。

  4、存取時應使用由數據庫JDBC驅動程序提供的LOB操作類。

  對於Oracle數據庫,應使用oracle.sql.CLOB和oracle.sql.BLOB。不使用由數據庫JDBC驅動程序提供的LOB類時,程序運行時易於出現“抽象方法調用”的錯誤,這是因為JDBC所定義的java.sql.Clob與 java.sql.Blob接口,其中的一些方法並未在數據庫廠家提供的驅動程序中真正實現。

  5、存取手段與文件操作相仿。

  對於BLOB類型,應用InputStream/OutputStream類,此類不進行編碼轉換,逐個字節存取。oracle.sql.BLOB類相應提供了getBinaryStream()和getBinaryOutputStream()兩個方法,前一個 方法用於讀取Oracle的BLOB字段,後一個方法用於將數據寫入Oracle的BLOB字段。

  對於CLOB類型,應用Reader/Writer類,此類進行編碼轉換。oracle.sql.CLOB類相應 提供了getCharacterStream()和getCharacterOutputStream()兩個方法,前一個方法用於讀取Oracle的 CLOB字段,後一個方法用於將數據寫入Oracle的CLOB字段。

  需要說明的是,為了大幅提高程序執行效率,對BLOB/CLOB字段的讀寫操作,應該使用緩沖操作類(帶 Buffered前綴),即:BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter。 例程中全部使用了緩沖操作類。

JDBC 復習3 存取Oracle大數據 clob blob