OceanBase LONG 和 LONG RAW 數(shù)據(jù)類型

2021-06-30 15:40 更新

當查詢選擇一個或多個 LONG 或 LONG RAW 列時,OceanBase Connector/J 將這些列以流模式傳輸?shù)娇蛻舳恕?/p>

在流模式下,OceanBase Connector/J 一般不會從網(wǎng)絡(luò)讀取 LONG 或 LONG RAW 列的數(shù)據(jù)。在使用代碼調(diào)用 getXXX 方法讀取列數(shù)據(jù)之前,列數(shù)據(jù)將保留在網(wǎng)絡(luò)通信通道中。除了讀取列數(shù)據(jù)外,任何連接使用都會將列數(shù)據(jù)從通道中丟棄。雖然流模式可以有效利用內(nèi)存并最大程度地減少往返通信,但它會干擾其他數(shù)據(jù)庫操作。

要訪問 LONG 列中的數(shù)據(jù),您可以將該列作為 Java InputStream 對象,并使用 InputStream 對象的 read 方法獲取。也可以將數(shù)據(jù)作為 String 或 byte 數(shù)組,通過執(zhí)行流傳輸獲取。

三種流類型都可以獲取 LONG 和 LONG RAW 數(shù)據(jù)。驅(qū)動程序?qū)⒏鶕?jù)數(shù)據(jù)庫和驅(qū)動程序的字符集進行執(zhí)行轉(zhuǎn)換。

注意 
不要創(chuàng)建帶有 LONG 列的表??梢愿挠么髮ο螅?code>LOB)列:CLOBNCLOB 和 BLOB。因為 LOB 列的使用限制遠少于 LONG 列,所以建議將現(xiàn)有的 LONG 列轉(zhuǎn)換為 LOB 列。

LONG RAW 數(shù)據(jù)轉(zhuǎn)換

調(diào)用 getBinaryStream 返回 RAW 數(shù)據(jù)。調(diào)用 getAsciiStream 會將 RAW 數(shù)據(jù)轉(zhuǎn)換為十六進制并返回相應(yīng)的 ASCII。調(diào)用 getUnicodeStream 會將 RAW 數(shù)據(jù)轉(zhuǎn)換為十六進制并返回 Unicode 字符。

LONG 數(shù)據(jù)轉(zhuǎn)換

使用 getAsciiStream 獲取 LONG 數(shù)據(jù)時,驅(qū)動程序會假定數(shù)據(jù)庫中的基礎(chǔ)數(shù)據(jù)使用 US7ASCII 或 WE8ISO8859P1 字符集。如果假設(shè)為真,則驅(qū)動程序?qū)⒎祷嘏c ASCII 字符相對應(yīng)的字節(jié)。如果數(shù)據(jù)庫未使用 US7ASCII 或 WE8ISO8859P1 字符集,則調(diào)用 getAsciiStream 將返回無意義的信息。

使用 getUnicodeStream 獲取 LONG 數(shù)據(jù)時,將獲得 UTF-16 編碼的 Unicode 字符流。

使用 getBinaryStream 獲取 LONG 數(shù)據(jù)時,如果數(shù)據(jù)庫字符集不是 US7ASCII 或 WE8ISO8859P1,則調(diào)用 getBinaryStream 將返回 UTF-8。如果服務(wù)器端字符集是 US7ASCII 或 WE8ISO8859P1,則調(diào)用將返回 US7ASCII 字節(jié)流。

注意 
將 LONG 或 LONG RAW 列作為流進行接收時,需要特別注意在數(shù)據(jù)庫中檢索的列的順序。
LONG 和 LONG RAW 數(shù)據(jù)轉(zhuǎn)換的詳細信息如下表所示。

數(shù)據(jù)類型

BinaryStream

AsciiStream

UnicodeStream

LONG

字節(jié)表示 Unicode UTF-8 中的字符。如果數(shù)據(jù)庫字符集為 US7ASCII 或 WE8ISO8859P1,則這些字節(jié)表示 US7ASCII 或 WE8ISO8859P1 中的字符。

字節(jié)表示 ISO-Latin-1(WE8ISO8859P1)編碼中的字符。

字節(jié)代表 Unicode UTF-16 編碼的字符。

LONG RAW

數(shù)據(jù)不變數(shù)據(jù)。

十六進制字節(jié)的 ASCII 表示形式。

十六進制字節(jié)的 Unicode 表示形式。

示例

getXXXStream 方法的功能之一是能夠以增量方式獲取數(shù)據(jù),而 getBytes 在一次調(diào)用中就獲取所有數(shù)據(jù)。以下是獲取二進制數(shù)據(jù)流的示例。

示例 1:使用 getBinaryStream 方法獲取 LONG RAW 數(shù)據(jù)

  1. 創(chuàng)建表 stream01,存儲與名稱 SAMPLE 相關(guān)的 LONG RAW 數(shù)據(jù)列。

    CREATE TABLE stream01 (name VARCHAR2 (50), giftype LONG RAW);
    INSERT INTO stream01 VALUES ('SAMPLE', '1234567890123');
  2. 將 LONG RAW 列中的數(shù)據(jù)寫入名為 sample.gif 的文件中。

    ResultSet rs = st.executeQuery 
                     ("select giftype from stream01 where NAME='SAMPLE'");
  3. 使用 getBinaryStream 方法獲取 LONG RAW 數(shù)據(jù)。

    // 獲取第一行
    if (rs.next())
    {
        // 以流形式獲取 GIF 數(shù)據(jù)
        InputStream gif_type = rs.getBinaryStream (1);
       try
       {
          FileOutputStream file = null;
          file = new FileOutputStream ("sample.gif");
          int chunk;
          while ((chunk = gif_type.read()) != -1)
             file.write(chunk);
       }
       catch (Exception e)
       {
          String err = e.toString();
          System.out.println(err);
       }
       finally
       {
          if file != null()
             file.close();
       }
    } 

上述示例中,調(diào)用 getBinaryStream 返回的 InputStream 對象直接從數(shù)據(jù)庫連接中讀取數(shù)據(jù)。

示例 2:使用 getBytes 方法獲取 LONG RAW 數(shù)據(jù)

本示例使用 getBytes 獲取 giftype 列的內(nèi)容,驅(qū)動程序?qū)⒃谝淮握{(diào)用中獲取所有數(shù)據(jù),并將其存儲在字節(jié)數(shù)組中。

ResultSet rs2 = st.executeQuery 
                  ("select giftype from streame01 where NAME='SAMPLE'"); 

// 獲取第一行
if (rs2.next())
{
   // 以流形式獲取 GIF 數(shù)據(jù)
   byte[] bytes = rs2.getBytes(1);
   try
   {
      FileOutputStream file = null;
      file = new FileOutputStream ("sample2.gif");
      file.write(bytes);
   }
   catch (Exception e)
   {
      String err = e.toString();
      System.out.println(err);
   }
   finally
   {
      if file != null()
         file.close();
   }
}

因為 LONG RAW 列最多可以包含 2 GB 的數(shù)據(jù),所以與 getBinaryStream 示例相比,getBytes 示例可以使用更多的內(nèi)存。如果不知道 LONG 或 LONG RAW 列中數(shù)據(jù)的最大大小,請使用流。

說明 
  • OceanBase Connector/J 可以自動流傳輸任何 LONG 和 LONG RAW 列。但在某些情況下,您可能希望避免數(shù)據(jù)流傳輸。例如,當 LONG 列很小時,這種情況可能就要避免遞增式返回數(shù)據(jù),而是采用一次調(diào)用就返回數(shù)據(jù)。
  • 為避免流傳輸,請使用 defineColumnType 方法重新定義 LONG 列的類型。例如,可以將 LONG 或 LONG RAW 列重新定義為 VARCHAR 或 VARBINARY 類型,則驅(qū)動程序?qū)⒉粫詣恿鱾鬏敂?shù)據(jù)。
  • 如果使用 defineColumnType 重新定義列類型,則必須在查詢中聲明列的類型。否則,executeQuery 將執(zhí)行失敗。另外,必須將 Statement 對象轉(zhuǎn)換為 oceanbase.jdbc.oceanbaseStatement。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號