JavaでBYTEAデータを使用する

The BYTEA data type stores a binary string in a sequence of bytes; digital images and sound files are often stored as binary data. Advanced Server can store and retrieve binary data via the BYTEA data type.

次のJavaサンプルは、 BYTEA データをAdvancedServerデータベースに保存し、そのデータを取得する方法を示しています。この例では少しセットアップが必要です。リスト1.12-a、1.12-b、および1.12-cは、Javaの例のサーバー側環境を作成します。

Listing 1.12-a creates a table (emp_detail) that stores BYTEA data. emp_detail contains two columns: the first column stores an employee’s ID number (type INT) and serves as the primary key for the table; the second column stores a photograph of the employee in BYTEA format:

CREATE TABLE emp_detail
(
  empno INT4 PRIMARY KEY,
  pic   BYTEA
);

リスト1.12-bは、 emp_detail テーブルに行を挿入するプロシージャ( ADD_PIC )を作成します。

CREATE OR REPLACE PROCEDURE ADD_PIC(p_empno IN int4, p_photo IN bytea) AS
BEGIN
  INSERT INTO emp_detail VALUES(p_empno, p_photo);
END;

最後に、リスト1.12-cは、特定の従業員の写真を返す関数( GET_PIC )を作成します。

CREATE OR REPLACE FUNCTION GET_PIC(p_empno IN int4) RETURN BYTEA IS
DECLARE
  photo BYTEA;
BEGIN
  SELECT pic INTO photo from EMP_DETAIL WHERE empno = p_empno;
  RETURN photo;
END;

BYTEAデータをAdvancedServerデータベースに挿入する

リスト1.13は ADD_PIC プロシージャ(リスト1.12-bを参照)を呼び出して、クライアントファイルシステムからサーバー上の emp_detail テーブルに写真をコピーするJavaメソッドを示しています。

public void InsertPic(Connection con)
{
  try
  {
    Console c = System.console();
    int empno = Integer.parseInt(c.readLine("Employee No :"));
    String fileName = c.readLine("Image filename :");
    File f = new File(fileName);

    if(!f.exists())
    {
      System.out.println("Image file not found. Terminating...");
      return;
    }

    CallableStatement stmt = con.prepareCall("{call ADD_PIC(?, ?)}");
    stmt.setInt(1, empno);
    stmt.setBinaryStream(2, new FileInputStream(f), (int)f.length());
    stmt.execute();
    System.out.println("Added image for Employee "+empno);
  }
  catch(Exception err)
  {
    System.out.println("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

InsertPic() は、従業員番号と画像ファイルの名前をユーザーに要求します:

int empno = Integer.parseInt(c.readLine("Employee No :"));
String fileName = c.readLine("Image filename :");

要求されたファイルが存在しない場合、 InsertPic() はエラーメッセージを表示して終了します:

File f = new File(fileName);

if(!f.exists())
{
  System.out.println("Image file not found. Terminating...");
  return;
}

次に、 InsertPic() は ADD_PIC プロシージャを呼び出す CallableStatement オブジェクト( stmt )を準備します。最初のプレースホルダー(?)は、 ADD_PIC (p_empno) で予期される最初のパラメーターを表します。2番目のプレースホルダーは2番目のパラメーター( p_photo )を表します。これらのプレースホルダーに実際の値を提供するために、 InsertPic() は2つのセッターメソッドを呼び出します。最初のパラメーターは INTEGER 型であるため、 InsertPic() は setInt() メソッドを呼び出して p_empno の値を提供します。2番目のパラメーターは BYTEA 型であるため、 InsertPic() はバイナリセッターメソッドを使用します。この場合、メソッドは setBinaryStream() です:

CallableStatement stmt = con.prepareCall("{call ADD_PIC(?, ?)}");
stmt.setInt(1, empno);
stmt.setBinaryStream(2 ,new FileInputStream(f), f.length());

プレースホルダーが実際の値にバインドされたので、 InsertPic() は CallableStatement を実行します:

stmt.execute();

すべてうまくいけば、 InsertPic() は画像がテーブルに追加されたことを確認するメッセージを表示します。エラーが発生した場合、 catch ブロックはユーザーにメッセージを表示します:

System.out.println("Added image for Employee \""+empno);
catch(Exception err)
{
  System.out.println("An error has occurred.");
  System.out.println("See full details below.");
  err.printStackTrace();
}

AdvancedServerデータベースからBYTEAデータを取得する

Now that you know how to insert BYTEA data from a Java application, Listing 1.14 demonstrates how to retrieve BYTEA data from the server:

public static void GetPic(Connection con)
{
  try
  {
    Console c = System.console();
    int empno = Integer.parseInt(c.readLine("Employee No :"));
    CallableStatement stmt = con.prepareCall("{?=call GET_PIC(?)}");
    stmt.setInt(2, empno);
    stmt.registerOutParameter(1, Types.BINARY);
    stmt.execute();
    byte[] b = stmt.getBytes(1);

    String fileName = c.readLine("Destination filename :");
    FileOutputStream fos = new FileOutputStream(new File(fileName));
    fos.write(b);
    fos.close();
    System.out.println("File saved at \""+fileName+"\"");
  }
  catch(Exception err)
  {
    System.out.println("An error has occurred.");
    System.out.println("See full details below.");
    err.printStackTrace();
  }
}

GetPic() は、ユーザーに従業員ID番号の入力を求めることから始まります。

int empno = Integer.parseInt(c.readLine("Employee No :"));

次に、 GetPic() は1つの IN パラメーターと1つの OUT パラメーターで CallableStatement を準備します。最初のパラメーターは、データベースから取得した写真を含む OUT パラメーターです。写真は BYTEA データであるため、 GetPic() はパラメーターを Type.BINARY として登録します。2番目のパラメーターは従業員番号( INT )を保持する IN パラメーターであるため、 GetPic() は setInt() メソッドを使用して2番目のパラメーターの値を提供します。

CallableStatement stmt = con.prepareCall("{?=call GET_PIC(?)}");
stmt.setInt(2, empno);
stmt.registerOutParameter(1, Types.BINARY);

次に、 GetPic() は getBytes ゲッターメソッドを使用して CallableStatement から BYTEA データを取得します。

stmt.execute();
byte[] b = stmt.getBytes(1);

プログラムは、写真を保存するファイルの名前をユーザーに要求します。

String fileName = c.readLine("Destination filename :");

FileOutputStream オブジェクトは、写真を含むバイナリデータを宛先ファイル名に書き込みます。

FileOutputStream fos = new FileOutputStream(new File(fileName));
fos.write(b);
fos.close();

最後に、 GetPic() はファイルが新しい場所に保存されたことを確認するメッセージを表示します:

System.out.println("File saved at \""+fileName+"\"");