When a query selects one or more LONG or LONG RAW columns, OceanBase Connector/J transmits these columns to the client in streaming mode.
In streaming mode, OceanBase Connector/J generally does not read the data of LONG or LONG RAW columns from the network. Before you call the getXXX method to read column data in your code, the column data remains in the network communication channel. Any connection that does not read the column data will discard the column data from the channel. Although streaming mode effectively utilizes memory and minimizes round-trip communication, it can interfere with other database operations.
To access the data in a LONG column, you can treat the column as a Java InputStream object and use the read method of the InputStream object. You can also retrieve the data as a String or byte array by performing a streaming transfer.
All three streaming types can retrieve LONG and LONG RAW data. The driver performs data conversion based on the character sets of the database and the driver.
Notice
Do not create tables with `LONG` columns. Instead, use large object (LOB) columns: CLOB, NCLOB, and BLOB. LOB columns have significantly fewer usage restrictions compared to LONG columns, so it is recommended to convert existing LONG columns to LOB columns.
LONG RAW data conversion
Calling getBinaryStream returns RAW data. Calling getAsciiStream converts RAW data to hexadecimal and returns the corresponding ASCII. Calling getUnicodeStream converts RAW data to hexadecimal and returns Unicode characters.
LONG data conversion
When you call getAsciiStream to retrieve LONG data, the driver assumes that the underlying data in the database uses the US7ASCII or WE8ISO8859P1 character set. If this assumption is true, the driver returns bytes corresponding to ASCII characters. If the database does not use the US7ASCII or WE8ISO8859P1 character set, calling getAsciiStream will return meaningless information.
When you call getUnicodeStream to retrieve LONG data, you get a Unicode character stream encoded in UTF-16.
When you call getBinaryStream to retrieve LONG data, if the database character set is not US7ASCII or WE8ISO8859P1, the call to getBinaryStream will return UTF-8. If the server-side character set is US7ASCII or WE8ISO8859P1, the call will return a US7ASCII byte stream.
Notice
When receiving LONG or LONG RAW columns as streams, pay special attention to the order of the columns retrieved from the database.
The following table shows the details of LONG and LONG RAW data conversion.
Data Type |
BinaryStream |
AsciiStream |
UnicodeStream |
|---|---|---|---|
| LONG | Bytes representing Unicode UTF-8 characters. If the database character set is US7ASCII or WE8ISO8859P1, these bytes represent characters in US7ASCII or WE8ISO8859P1. |
Bytes representing characters in ISO-Latin-1 (WE8ISO8859P1) encoding. |
Bytes representing Unicode UTF-16 encoded characters. |
| LONG RAW | Data remains unchanged. | ASCII representation of hexadecimal bytes. | Unicode representation of hexadecimal bytes. |
Example
One of the functions of the getXXXStream method is to retrieve data incrementally, while getBytes retrieves all data in a single call. Here is an example of retrieving a binary data stream.
Example 1: Use the getBinaryStream method to retrieve LONG RAW data
Create a table named
stream01to store aLONG RAWdata column related to theSAMPLEcolumn.CREATE TABLE stream01 (name VARCHAR2 (50), giftype LONG RAW); INSERT INTO stream01 VALUES ('SAMPLE', '1234567890123');Write the data in the
LONG RAWcolumn to a file namedsample.gif.ResultSet rs = st.executeQuery ("select giftype from stream01 where NAME='SAMPLE'");Use the
getBinaryStreammethod to retrieve theLONG RAWdata.// Retrieve the first row if (rs.next()) { // Retrieve the GIF data in stream form 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(); } }
In the preceding example, the InputStream object returned by the getBinaryStream method directly reads data from the database connection.
Example 2: Use the getBytes method to retrieve LONG RAW data
In this example, the getBytes method is used to retrieve the contents of the giftype column. The driver retrieves all data in a single call and stores it in a byte array.
ResultSet rs2 = st.executeQuery
("select giftype from stream01 where NAME='SAMPLE'");
// Retrieve the first row
if (rs2.next())
{
// Retrieve the GIF data in stream form
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();
}
}
Because a LONG RAW column can contain up to 2 GB of data, the getBytes example can use more memory than the getBinaryStream example. If you are unsure of the maximum size of data in a LONG or LONG RAW column, use a stream.
Note
- OceanBase Connector/J automatically streams any
LONGandLONG RAWcolumns. However, in some cases, you may want to avoid streaming data. For example, when theLONGcolumn is small, you may want to retrieve all data in a single call instead of incrementally. - To avoid streaming, use the
defineColumnTypemethod to redefine the type of theLONGcolumn. For example, you can redefine aLONGorLONG RAWcolumn as aVARCHARorVARBINARYcolumn. In this case, the driver does not automatically stream data. - If you use the
defineColumnTypemethod to redefine the column type, you must declare the column type in the query. Otherwise, theexecuteQuerymethod fails. In addition, you must convert theStatementobject to aoceanbase.jdbc.oceanbaseStatementobject.
