JDBC ORACLE BLOB處理

來源:互聯網
上載者:User

標籤:oracle   jdbc   java   blob   儲存   

LOB,即Large Objects(大對象),是用來儲存大量的二進位和文本資料的一種資料類型(一個LOB欄位可儲存可多達4GB的資料)。
LOB 分為兩種類型:內部LOB和外部LOB。
    內部LOB將資料以位元組流的形式儲存在資料庫的內部。因而,內部LOB的許多操作都可以參與事務,
也可以像處理普通資料一樣對其進行備份和恢複操作。Oracle支援三種類型的內部LOB:
BLOB(位元據)  
CLOB(單位元組字元資料) 
NCLOB(多位元組字元資料)。
CLOB和NCLOB類型適用於儲存超長的文本資料,BLOB欄位適用於儲存大量的位元據,像、視頻、音頻,檔案等。


目前只支援一種外部LOB類型,即BFILE類型。在資料庫內,該類型僅儲存資料在作業系統中的位置資訊,
而資料的實體以外部檔案的形式存在於作業系統的檔案系統中。因而,該類型所表示的資料是唯讀,不參與事務。
該類型可協助使用者管理大量的由外部程式訪問的檔案.


使用JDBC來寫入Blob型資料到Oracle中 :
Oracle的Blob欄位比long欄位的效能要好,可以用來儲存片之類的位元據。 
Oracle的BLOB欄位由兩部分組成:資料(值)和指向資料的指標(定位器)。儘管值與
 表自身一起儲存,但是一個BLOB列並不包含值,僅有它的定位指標。為了使用大對象,程式必須聲明定位器類型的本地變數。
當Oracle內部LOB被建立時,定位器被存放在列中,值被存放在LOB段中,LOB段是在資料庫內部表的一部分。
因為Blob自身有一個cursor,當寫入Blob欄位必須使用指標(定位器)對Blob進行操作,因而在寫入Blob之前,
 必須獲得指標(定位器)才能進行寫入
如何獲得Blob的指標(定位器) :需要先插入一個empty的blob,這將建立一個blob的指標,然後再把這個empty
 的blob的指標查詢出來,這樣通過兩步操作,就獲得了blob的指標,可以真正的寫入blob資料了。 
具體步驟:
1、插入空blob insert into javatest(name,content) values(?,empty_blob()); 


2、獲得blob的cursor select content from javatest where name= ? for update; 
  注意:  須加for update,鎖定該行,直至該行被修改完畢,保證不產生並發衝突。
3、利用 io,和擷取到的cursor往資料庫寫資料流

案例:以下案例實現插入一張圖片,和擷取有一張圖片的查詢結果;
/* * 檔案名稱:BlobTest.java * 著作權:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改時間:2015-8-25 * 跟蹤單號: * 修改單號: * 修改內容: */package com.jdbc.cgc.blob;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;import oracle.sql.BLOB;import org.junit.Test;/** * <一句話功能簡述> <功能詳細描述> *  * @author 姓名 工號 * @version [版本號碼, 2015-8-25] * @see [相關類/方法] * @since [產品/模組版本] */public class BlobTest{        /**     * <一句話功能簡述>測試方法,插入一條資料,資料中有一個列是Blob <功能詳細描述>     *      * @throws FileNotFoundException     * @see [類、類#方法、類#成員]     */    @Test    public void test00()        throws FileNotFoundException    {        // 注意: 對於empty_blob()應放在SQL語句中直接賦值, 使用預置語句的方式賦值無法實現.        String sql = "insert into t_emp13(first_name,salary,picture) values (?,?,Empty_BLOB())";        // 查詢Blob 注意進行 行鎖定 後邊的for update        String sqlQuery = "select picture from t_emp13 where first_name = ? and salary = ? for update";        updateBlob(sql, sqlQuery, "QQA122", 1233);    }        /**     * <一句話功能簡述>更新有blob的資料庫表 <功能詳細描述>     *      * @param sqlInsert     * @param sqlQuery     * @param args     * @see [類、類#方法、類#成員]     */    public void updateBlob(String sqlInsert, String sqlQuery, Object... args)    {        Connection conn = null;        PreparedStatement prepareStatement = null;        ResultSet rs = null;                OutputStream os = null;        FileInputStream fis = null;        try        {            // 現在表中插入空的Blob            conn = getConn();            // 事物處理前,取消Connection的預設提交行為            conn.setAutoCommit(false);            prepareStatement = conn.prepareStatement(sqlInsert);                        for (int i = 0; i < args.length; i++)            {                prepareStatement.setObject(i + 1, args[i]);            }            prepareStatement.executeUpdate();                        BLOB blob = null;                        prepareStatement = conn.prepareStatement(sqlQuery);                        for (int i = 0; i < args.length; i++)            {                prepareStatement.setObject(i + 1, args[i]);            }                        // prepareStatement.setString(1, "QQA");            rs = prepareStatement.executeQuery();            if (rs.next())            {                blob = (BLOB)rs.getBlob(1);            }            // 得到資料庫的輸出資料流            os = blob.getBinaryOutputStream();            // 得到要插入檔案的輸入資料流            fis = new FileInputStream("Tulips.jpg");                        byte[] b = new byte[1024];            int len;            while (-1 != (len = fis.read(b)))            {                os.write(b, 0, len);            }            // 清空流的緩衝            os.flush();            // 事物處理:如果事物處理成功則提交事物            conn.commit();        }        catch (Exception e)        {            e.printStackTrace();            try            {                // 事物處理:如果出現異常 則在catch塊中復原事物                conn.rollback();            }            catch (SQLException e1)            {                e1.printStackTrace();            }        }        finally        {            if (null != fis)            {                try                {                    fis.close();                }                catch (IOException e)                {                    e.printStackTrace();                }            }            if (null != os)            {                try                {                    os.close();                }                catch (IOException e)                {                    e.printStackTrace();                }            }                        releaseSource(prepareStatement, conn, null);        }    }        /**     * <一句話功能簡述>測試方法,查詢有blob的表 <功能詳細描述>     *      * @see [類、類#方法、類#成員]     */    @Test    public void test01()    {        String sql = "select picture from t_emp13 where first_name = ?";        queryBlob(sql, "QQA122");    }        /**     * <一句話功能簡述>查詢有Blob的表 方法 <功能詳細描述>     *      * @param sql     * @param args     * @see [類、類#方法、類#成員]     */    public void queryBlob(String sql, Object... args)    {        Connection conn = null;        PreparedStatement prepareStatement = null;        ResultSet rs = null;                FileOutputStream fos = null;        InputStream is = null;                try        {            conn = getConn();            // 事物處理前,取消Connection的預設提交行為            conn.setAutoCommit(false);            prepareStatement = conn.prepareStatement(sql);            for (int i = 0; i < args.length; i++)            {                prepareStatement.setObject(i + 1, args[i]);            }            rs = prepareStatement.executeQuery();            if (rs.next())            {                BLOB blob = (BLOB)rs.getBlob(1);                is = blob.getBinaryStream();                                fos = new FileOutputStream(new File("test.png"));                                byte[] b = new byte[1024];                int len;                                while (-1 != (len = is.read(b)))                {                    fos.write(b, 0, len);                }                fos.flush();            }            // 事物處理:如果事物處理成功則提交事物            conn.commit();                    }        catch (Exception e)        {            e.printStackTrace();            try            {                // 事物處理:如果出現異常 則在catch塊中復原事物                conn.rollback();            }            catch (SQLException e1)            {                e1.printStackTrace();            }        }        finally        {            if (null != is)            {                try                {                    is.close();                }                catch (IOException e)                {                    e.printStackTrace();                }            }                        if (null != fos)            {                try                {                    fos.close();                }                catch (IOException e)                {                    e.printStackTrace();                }            }                        releaseSource(prepareStatement, conn, rs);        }    }        /**     * <一句話功能簡述> 串連資料庫 <功能詳細描述>     *      * @return     * @throws Exception     * @see [類、類#方法、類#成員]     */    public Connection getConn()        throws Exception    {        String dirverName = null;        String jdbcUrl = null;        String user = null;        String password = null;                Properties propertoes = new Properties();        InputStream is = getClass().getClassLoader().getResourceAsStream("jdbc.properties");        propertoes.load(is);                dirverName = propertoes.getProperty("driver");        jdbcUrl = propertoes.getProperty("jdbcURL");        user = propertoes.getProperty("user");        password = propertoes.getProperty("password");                Class.forName(dirverName);                // 通過DriverManager的getConnection擷取資料庫連接        Connection connection = DriverManager.getConnection(jdbcUrl, user, password);                return connection;    }        /**     * <一句話功能簡述>釋放資料庫資源 <功能詳細描述>     *      * @param statement     * @param conn     * @param resultSet     * @see [類、類#方法、類#成員]     */    public void releaseSource(Statement statement, Connection conn, ResultSet resultSet)    {        if (null != resultSet)        {            try            {                resultSet.close();            }            catch (SQLException e)            {                e.printStackTrace();            }        }                if (null != statement)        {            try            {                statement.close();            }            catch (Exception e)            {                e.printStackTrace();            }        }        if (null != conn)        {            try            {                conn.close();            }            catch (Exception e)            {                e.printStackTrace();            }        }    }}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

JDBC ORACLE BLOB處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.