Updating image data in the database

jConnect has a TextPointer class with sendData methods for updating an image column in an Adaptive Server or SQL Anywhere database. In earlier versions of jConnect, you had to send image data using the setBinaryStream method in java.sql.PreparedStatement. Currently the TextPointer.sendData methods use java.io.InputStream and greatly improve performance when you send image data to an Adaptive Server database.

WARNING!  Using the TextPointer class with sendData() method may affect the application as TextPointer is not a standard JDBC form.

Sybase recommends you use PreparedStatement.setBinaryStream(int paramIndex, InputStream image), a standard JDBC form to send image data. However, setBinaryStream() may consume much more memory on procedure cache than the TextPointer class when large image data is handled.

Until a replacement for the TextPointer class is implemented, Sybase will continue supporting it.

To obtain instances of the TextPointer class, you can use either of two getTextPtr methods in SybResultSet:


Public methods in the TextPointer class

The com.sybase.jdbcx package contains the TextPointer class. Its public method interface is:

public void sendData(InputStream is, boolean log) 
   throws SQLException
public void sendData(InputStream is, int length,
   boolean log) throws SQLException
public void sendData(InputStream is, int offset, 
   int length, boolean log) throws SQLException
public void sendData(byte[] byteInput, int offset, 
   int length, boolean log) throws SQLEXception

where:

StepsUpdating an image column with TextPointer.sendData

To update a column with image data:

  1. Get a TextPointer object for the row and column that you want to update.

  2. Use TextPointer.sendData to execute the update.

The next two sections illustrate these steps with an example. In the example, image data from the file Anne_Ringer.gif is sent to update the pic column of the au_pix table in the pubs2 database. The update is for the row with author ID 899-46-2035.

Getting a TextPointer object

text and image columns contain timestamp and page-location information that is separate from their text and image data. When data is selected from a text or image column, this extra information is “hidden” as part of the result set.

A TextPointer object for updating an image column requires this hidden information but does not need the image portion of the column data. To get this information, you need to select the column into a ResultSet object and then use SybResultSet.getTextPtr, which extracts text-pointer information, ignores image data, and creates a TextPointer object. See the following code for an example.

When a column contains a significant amount of image data, selecting the column for one or more rows and waiting to get all the data is likely to be inefficient, since the data is not used. To shortcut this process, use the set textsize command to minimize the amount of data returned in a packet. The following code example for getting a TextPointer object includes the use of set textsize for this purpose.

/*
 * Define a string for selecting pic column data for author ID 
 * 899-46-2035.
 */
 String getColumnData = "select pic from au_pix where au_id = '899-46-2035'";
 
 /*
 * Use set textsize to return only a single byte of column data
 * to a Statement object. The packet with the column data will
 * contain the "hidden" information necessary for creating a
 * TextPointer object.
 */
 Statement stmt= connection.createStatement();
 stmt.executeUpdate("set textsize 1");
 
 /*
 * Select the column data into a ResultSet object--cast the 
 * ResultSet to SybResultSet because the getTextPtr method is 
 * in SybResultSet, which extends ResultSet.
 */
 SybResultSet rs = (SybResultSet)stmt.executeQuery(getColumnData);
 
 /*
 * Position the result set cursor on the returned column data 
 * and create the desired TextPointer object.
 */
 rs.next();
 TextPointer tp = rs.getTextPtr("pic");
 
 /* 
 * Now, assuming we are only updating one row, and won’t need
 * the minimum textsize set for the next return from the server,
 * we reset textsize to its default value.
 */
 stmt.executeUpdate("set textsize 0");


Executing the update with TextPointer.sendData

The following code uses the TextPointer object from the preceding section to update the pic column with image data in the file Anne_Ringer.gif.

/*
 *First, define an input stream for the file.
 */
 FileInputStream in = new FileInputStream("Anne_Ringer.gif");
 
 /*
 * Prepare to send the input stream without logging the image data 
 * in the transaction log.
 */
 boolean log = false;
 
 /*
 * Send the image data in Anne_Ringer.gif to update the pic 
 * column for author ID 899-46-2035.
 */
 tp.sendData(in, log);

See the TextPointers.java sample in the sample2 subdirectories under your jConnect installation directory.