MySQL の BLOB (Binary Large Object) を使う (Java と Eclipse を利用)
【概要】
MySQL の利用において、BLOB(Binary Large Object)を扱う Java プログラムの実装方法を、サンプルコードとともに解説する。開発環境として Eclipse を使用する。
Java と SQL の連携には JDBC を使用する。この仕組みにより、Java プログラムから SQL クエリをデータベースへ送信し、実行結果を処理できる。両者の間のデータ交換は変数を介して行う。
Java コードに SQL クエリを組み込み、SQL の実行結果(複数レコードで構成される)をループ処理で Java の変数に順次格納する。核となる部分は次のとおりである。
ResultSet rs = execute("SELECT * FROM commodity");
DecimalFormat dformat = new DecimalFormat("#,###円");
while (rs.next()) {
int t = rs.getInt("type");
String n = rs.getString("name");
int p = rs.getInt("price");
System.out.println(t + " " + n + " " + dformat.format(p));
}
【目次】
【サイト内の関連ページ】
必要なソフトウェア環境
- Windows 環境における Java JDK(Temurin 25 JDK)のセットアップが完了していること。インストール後、JDK のインストールディレクトリが存在することを確認する。
- Eclipse の導入ガイドに従って開発環境の導入が完了していること。
- MySQL のデータベース環境が構築されていること。
事前設定と環境構成
このページのプログラムは、以下の設定を前提とする。環境が異なる場合は、プログラムコードを適切に修正する。
データベース名、および MySQL アクセス用の一般ユーザアカウント(ユーザ名とパスワード)の設定は次のとおりである。
- データベース名: testdb
データベース名は、使用するデータベースを識別する名称である。半角英数字および記号のみを使用し、スペースを含めない。既存のデータベースの利用も、新規作成も可能である。
- MySQL アクセス用一般ユーザアカウント情報
- ユーザ名: testuser
- パスワード: hoge$#34hoge5
データベース testdb に対する適切なアクセス権限を持つユーザとして設定する。
新規データベースおよび新規一般ユーザアカウントを作成する場合は、MySQL コマンドライン・クライアントまたは MySQL Workbench を使用して、以下のコマンドを実行する。
CREATE DATABASE `testdb` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'hoge$#34hoge5'; GRANT ALL ON `testdb`.* TO 'testuser'@'localhost';セキュリティ対策として、実運用環境では hoge$#34hoge5 ではなく、十分な強度を持つパスワードを設定する。
MySQL の利用における重要な設定項目は次のとおりである。
- JDBC ドライバクラス: com.mysql.cj.jdbc.Driver(MySQL Connector/J の現行ドライバクラス)
- MySQL 用 JDBC の jar ファイル: mysql-connector-j の jar(本資料ではプロジェクトに追加して使用する)
MySQL への JDBC 接続に必要な Connector/J は、https://dev.mysql.com/downloads/connector/j/ からダウンロードして展開する。
ダウンロードの詳細手順については、MySQL Connector/J のダウンロードガイドを参照のこと。
テスト用データベースの構築
テスト環境として、以下の SQL コマンドを実行し、BLOBtest テーブルを作成する。あわせて、後続の Java プログラムで更新する行(主キー bid の値が 1 の行)をあらかじめ挿入しておく。
CREATE TABLE BLOBtest (
bid INTEGER PRIMARY KEY NOT NULL,
bytes BLOB
);
INSERT INTO BLOBtest(bid) VALUES (1);
* SQL の実行には、Eclipse データツール・プラットフォームの活用を推奨する。
Eclipse における JDBC プログラム実装手順
Eclipse の事前設定とクラス定義の準備
Eclipse のプロジェクト構成を以下のように設定する。既存の同名プロジェクトがある場合は、プロジェクト名を適切に変更する。
- プロジェクト名: HelloWorld
- パッケージ名: hoge.hoge.com
- メインクラス名: HelloWorld
- プロジェクトとパッケージの作成手順の詳細は、Eclipse における JDBC プログラミングガイドを参照のこと。
- JDBC の jar ファイルの追加を行う。
MySQL Connector/J の jar ファイル(mysql-connector-j の jar)をプロジェクトのビルドパスに追加する。
JDBC の jar ファイルが未導入の場合は、MySQL Connector/J のダウンロードガイドを参照して導入する。
クラス定義
クラス定義の実装手順を説明する。前提として、パッケージ hoge.hoge.com が作成されていることを確認する。
- エディタでクラス HelloWorld を定義する。
【実装の要点】
- テーブル BLOBtest には、BLOB 型の bytes 属性と、主キーとなる bid 属性が定義されている。
- Java の変数 bid と同じ値を持つ bid 行の bytes 属性へ、byte[] 型の変数 bytes の内容を設定するプログラムを実装する。
- データベース名やユーザ名が異なる環境で実行する場合は、適切な値へ設定を変更する。
- 既定では localhost への接続を前提とする。リモートデータベースへ接続する場合は、接続設定を適切に変更する。
【プログラムの核となる処理】
String updateSql = "UPDATE BLOBtest SET bytes = ? WHERE bid = ?"; PreparedStatement updateStatement = conn.prepareStatement(updateSql); // 第1引数(bytes 列)に、バイト配列を入力ストリームとして設定 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); updateStatement.setBinaryStream(1, bais, bytes.length); // 第2引数(bid)に、主キー値を設定 updateStatement.setInt(2, bid); // プリペアードステートメントの実行 updateStatement.executeUpdate(); bais.close(); updateStatement.close();問い合わせ結果は変数 rs(ResultSet)に格納される。rs には複数のレコード(行)が含まれ、
while (rs.next())による反復処理で各行を順に処理する。各行の属性値は、getInt("属性名")やgetString("属性名")などで取り出す。package hoge.hoge.com; import java.io.ByteArrayInputStream; import java.sql.*; import java.text.DecimalFormat; import java.util.Properties; public class HelloWorld { // MySQL Connector/J のドライバクラス private static final String JDBCDriver = "com.mysql.cj.jdbc.Driver"; // 下記の変数を環境に合わせて設定する private static final String DBNAME = "testdb"; // データベース名 private static final String USER = "testuser"; // データベースのユーザ名 private static final String PASS = "hoge$#34hoge5"; // データベースのパスワード private static final String DBURL = "jdbc:mysql://localhost/" + DBNAME; private static Statement stmt = null; private static Connection conn = null; public static void main(String[] args) throws SQLException { printTable(); byte[] d = new byte[100]; d[0] = 1; insertBLOBdata(1, d); printTable(); } public static void insertBLOBdata(int bid, byte[] bytes) throws SQLException { connect(USER, PASS); String updateSql = "UPDATE BLOBtest SET bytes = ? WHERE bid = ?"; PreparedStatement updateStatement = conn.prepareStatement(updateSql); // 第1引数(bytes 列)に、バイト配列を入力ストリームとして設定 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); updateStatement.setBinaryStream(1, bais, bytes.length); // 第2引数(bid)に、主キー値を設定 updateStatement.setInt(2, bid); updateStatement.executeUpdate(); bais.close(); updateStatement.close(); disconnect(); } public static void printTable() throws SQLException { connect(USER, PASS); ResultSet rs = execute("SELECT * FROM BLOBtest"); DecimalFormat dformat = new DecimalFormat("#,###"); while (rs.next()) { int bid = rs.getInt("bid"); byte[] bytes = rs.getBytes("bytes"); System.out.print(dformat.format(bid) + ":"); if (bytes == null) { System.out.println("(null)"); } else if (bytes.length == 0) { System.out.println("(empty)"); } else { System.out.printf("(%1$2x)", bytes.length); for (int i = 0; i < bytes.length; i++) { System.out.printf("%1$02x ", bytes[i] & 0xff); if ((i % 16) == 15) System.out.print("\n "); } System.out.println(); } } rs.close(); disconnect(); } // データベース接続 public static void connect(String user, String pass) throws SQLException { Properties prop = new Properties(); prop.put("user", user); prop.put("password", pass); conn = DriverManager.getConnection(DBURL, prop); } // データベース切断 public static void disconnect() throws SQLException { conn.close(); } // 問い合わせの実行 public static ResultSet execute(String sql) throws SQLException { stmt = conn.createStatement(); return stmt.executeQuery(sql); } } - ソースを保存
「ファイル」メニューの「保管」を選択するか、CTRL+S で保存する。保存すると自動的にコンパイルが実行される。コンパイル中にエラーや警告が発生した場合は、Eclipse の問題ビューに詳細が表示されるため確認する。
実行
- 実行対象クラスを選択し、右クリックする
プロジェクト・エクスプローラーには、パッケージ名の配下にクラスファイル一覧が表示される。実行対象のクラスファイル(この場合は HelloWorld.java)を右クリックで選択する。
- 「実行」 → 「Java アプリケーション」を選択する。キーボードショートカットとして Alt+Shift+X を押した後、J キーを押すことでも実行できる。
- 実行結果は次のように表示される。1 回目の printTable では bytes 列は空(null)であり、insertBLOBdata の後の 2 回目で、先頭 1 バイトが 01 のデータが表示される。
1:(null) 1:(64)01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... - 実行時に「接続できない」というエラーが発生した場合の対処:他のプロセスが接続を保持している可能性があるため、Eclipse を再起動してから再度実行する。解決しない場合は、DBNAME・USER・PASS・DBURL などの設定値を確認する。
(参考情報) Eclipse でデータベースの内容を確認するには、Eclipse のデータツール・プラットフォームの活用を推奨する。