Java -- JDBC 學習--處理Blob


Oracle LOB

LOB,即Large Objects(大對象),是用來存儲大量的二進制和文本數據的一種數據類型(一個LOB字段可存儲可多達4GB的數據)。
LOB 分為兩種類型:內部LOB和外部LOB。
內部LOB將數據以字節流的形式存儲在數據庫的內部。因而,內部LOB的許多操作都可以參與事務,也可以像處理普通數據一樣對其進行備份和恢復操作。Oracle支持三種類型的內部LOB:

  1. BLOB(二進制數據)  
  2. CLOB(單字節字符數據) 
  3. NCLOB(多字節字符數據)。

CLOB和NCLOB類型適用於存儲超長的文本數據,BLOB字段適用於存儲大量的二進制數據,如圖像、視頻、音頻,文件等。
目前只支持一種外部LOB類型,即BFILE類型。在數據庫內,該類型僅存儲數據在操作系統中的位置信息,而數據的實體以外部文件的形式存在於操作系統的文件系統中。因而,該類型所表示的數據是只讀的,不參與事務。該類型可幫助用戶管理大量的由外部程序訪問的文件。

MySQL BLOB

MySQL中,BLOB是一個二進制大型對象,是一個可以存儲大量數據的容器,它能容納不同大小的數據。
MySQL的四種BLOB類型(除了在存儲的最大信息量上不同外,他們是等同的)。

 

實際使用中根據需要存入的數據大小定義不同的BLOB類型。 需要注意的是:如果存儲的文件過大,數據庫的性能會下降。

使用JDBC來寫入Blob型數據到Oracle中

  1. Oracle的Blob字段比long字段的性能要好,可以用來保存如圖片之類的二進制數據。
  2. Oracle的BLOB字段由兩部分組成:數據(值)和指向數據的指針(定位器)。盡管值與表自身一起存儲,但是一個BLOB列並不包含值,僅有它的定位指針。為了使用大對象,程序必須聲明定位器類型的本地變量。
  3. 當Oracle內部LOB被創建時,定位器被存放在列中,值被存放在LOB段中,LOB段是在數據庫內部表的一部分。
  4. 因為Blob自身有一個cursor,當寫入Blob字段必須使用指針(定位器)對Blob進行操作,因而在寫入Blob之前,必須獲得指針(定位器)才能進行寫入
  5. 如何獲得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往數據庫寫數據流 。

 

插入 BLOB 類型的數據必須使用 PreparedStatement:因為 BLOB 類型的數據時無法使用字符串拼寫的。

舉個例子:

public void testInsertBlob(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        
        try {
            connection = JDBCTools.getConnection();
            String sql = "INSERT INTO customers(name, email, birth, picture)" 
                    + "VALUES(?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql);
            
            preparedStatement.setString(1, "ABCDE");
            preparedStatement.setString(2, "abcde@atguigu.com");
            preparedStatement.setDate(3, 
                    new Date(new java.util.Date().getTime()));
            
            InputStream inputStream = new FileInputStream("Hydrangeas.jpg");
            preparedStatement.setBlob(4, inputStream);
            
            preparedStatement.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            JDBCTools.releaseDB(null, preparedStatement, connection);
        }
    }

讀取 blob 數據:
  1. 使用 getBlob 方法讀取到 Blob 對象
  2. 調用 Blob 的 getBinaryStream() 方法得到輸入流。再使用 IO 操作即可.

舉個例子:

@Test
    public void readBlob(){
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        
        try {
            connection = JDBCTools.getConnection();
            String sql = "SELECT id, name customerName, email, birth, picture " 
                    + "FROM customers WHERE id = 13";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            
            if(resultSet.next()){
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                String email = resultSet.getString(3);
                
                System.out.println(id + ", " + name  + ", " + email);
                Blob picture = resultSet.getBlob(5);
                
                InputStream in = picture.getBinaryStream();
                System.out.println(in.available()); 
                
                OutputStream out = new FileOutputStream("flower.jpg");
                
                byte [] buffer = new byte[1024];
                int len = 0;
                while((len = in.read(buffer)) != -1){
                    out.write(buffer, 0, len);
                }
                
                in.close();
                out.close();
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            JDBCTools.releaseDB(resultSet, preparedStatement, connection);
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM