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+"\"");