MySQL の BLOB (Binary Large Object) の活用方法 - Java と Eclipse による実装ガイド
このページでは,MySQL の活用において,BLOB (Binary Large Object) を効率的に処理するJavaプログラムの実装方法を,詳細な解説と実践的なサンプルコードを用いて説明する.開発環境としてEclipseを使用する.
- Java プログラムにおける SQL プログラムの統合について解説する.
⇒ SQL はリレーショナルデータベースを操作するための標準的な問い合わせ言語である.Java と SQL の連携にはJDBCを使用する.この仕組みにより,Java プログラムから SQL クエリをデータベースに送信し,その実行結果を効率的に処理することが可能となる.両言語間のデータ交換は変数を介して実現される.
Java プログラムの核となる部分は以下の通りである. 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 ) );
* 上記のような SQL 実行結果の効率的な処理には,最適化されたプログラム構造の設計が不可欠である.
必要なソフトウェア環境
- Windows 環境における Java JDK 18 のセットアップが正常に完了していること.
インストール後,C:\Program Files\Java\jdk1.6.0_12 などのディレクトリが存在することを確認する.
- Eclipse の導入ガイドに従って開発環境のインストールが完了していること.
- MySQL のデータベース環境が適切に構築されていること.
事前設定と環境構成
設定内容について,このWebページで紹介するプログラムは,以下の設定を前提としている. 環境が異なる場合は,必要に応じてプログラムコードを適切に修正する.
データベース名および MySQL アクセス用の一般ユーザアカウント(ユーザ名とパスワード)の 設定は以下の通りである.
- データベース名: testdb
データベース名は,使用するデータベースを識別するための固有の名称である. 半角英数字および記号のみを使用し,スペースを含まない文字列を指定する. 既存のデータベースの利用,または新規データベースの作成のいずれも可能である.
- MySQL アクセス用一般ユーザアカウント情報
- ユーザ名: testuser
- パスワード: hoge$#34hoge5
データベース名 testdb に対する適切なアクセス権限を持つユーザとして設定する必要がある.
新規データベースおよび新規一般ユーザアカウントを作成する場合は, MySQL コマンドライン・クライアントまたは MySQL GUI Toolsを使用して,以下のコマンドを実行する.
* 各ツールの詳細な操作手順については,MySQL コマンドライン・クライアントの解説および MySQL GUI Tools の使用ガイドを参照のこと.
create database 'testdb' default character set cp932 collate cp932_japanese_ci; create user testuser identified by 'hoge$#34hoge5'; grant all on testdb.* to 'testuser';
セキュリティ対策として,実運用環境では hoge$#34hoge5 ではなく,十分な強度を持つパスワードを設定する.
MySQL の利用における重要な設定項目は以下の通りである.
- JDBC ドライバ: org.gjt.mm.mysql.Driver (MySQL 固有の設定値)
- MySQL 用 JDBC の jar ファイルパス: C:\Program Files\Java\mysql-connector-java-5.1.7\mysql-connector-java-5.1.7-bin.jar
MySQL への JDBC 接続に必要な Connector/J は, https://dev.mysql.com/downloads/connector/ からダウンロードし,指定のディレクトリに展開する(本資料では上記パスを前提として説明する).
ダウンロードの詳細手順については, 「MySQL コネクタ (Connector) Java のダウンロードガイド」を参照のこと.
テスト用データベースの構築
テスト環境として,以下の SQL コマンドを実行し,BLOBtest テーブルを作成してデータを格納する.
create table BLOBtest ( bid INTEGER primary key not null, bytes BLOB );
* SQL の効率的な実行には,Eclipse データツール・プラットフォームの活用を推奨する. 詳細な使用方法は専用ページで解説している.
Eclipse における JDBC プログラム実装手順
Eclipse の事前設定とクラス定義の準備
Eclipse のプロジェクト構成を以下のように設定する. 既存の同名プロジェクトがある場合は,プロジェクト名を適切に変更する.
- プロジェクト名: HelloWorld
- パッケージ名: hoge.hoge.com
- メインクラス名: HelloWorld
- プロジェクトとパッケージの作成手順の詳細は,Eclipse における JDBC プログラミングガイドを参照のこと.
- JDBC の jar ファイルの追加は環境構築において必須である.
C:\Program Files\Java\mysql-connector-java-5.1.7\mysql-connector-java-5.1.7-bin.jar をプロジェクトに追加する.
JDBC の jar ファイルが未導入の場合は,MySQL Connector Java のダウンロードガイドを参照して導入する.
クラス定義
クラス定義の実装手順について説明する. 前提条件として,パッケージ hoge.hoge.com が正しく作成されていることを確認する.
- エディタでクラス HelloWorld を定義する.
【実装の要点】
- テーブル BLOBtest には,BLOB型の bytes 属性と主キーとなる bid 属性が定義されている.
- テーブル BLOBtest において,Javaの変数 bid と同一の値を持つ bid 行の bytes 属性に対して,byte[]型の変数 bytes の内容を設定するプログラムを実装する.
- データベース名やユーザ名が異なる環境で実行する場合は,適切な値に設定を変更する.
- デフォルトでは localhost への接続を前提としているが,リモートデータベースに接続する場合は,接続設定を適切に変更する.
【プログラムの核となる処理】
実装における重要な処理部分を以下に示す.
String updateSql = "UPDATE BLOBtest SET bytes = ? WHERE bid = ?"; PreparedStatement updateStatement = conn.prepareStatement(updateSql); //ステートメントの第1引数にバイトストリームから流し込む ByteArrayInputStream bais = new ByteArrayInputStream(bytes); updateStatement.setBinaryStream(1,bais,bytes.length); //ステートメントの第2引数に,主キー値を格納 updateStatement.setInt(2, bid); //プリペアードステートメント実行 updateStatement.executeUpdate(); bais.close(); updateStatement.close();
- SQLクエリの実行結果は変数 rs に格納される.
- rs には複数のレコード(行)データが含まれており,これらを適切なJavaの単純型変数に変換する必要がある.
- while(rs.next() によるイテレーション処理により,rs 内の各レコード(行)を順次処理する.
- 各レコード(行)は複数の属性値で構成され,getInt("属性名")やgetString("属性名")メソッドを使用して,必要な属性値を効率的に抽出する.
package hoge.hoge.com; import java.sql.*; import java.text.DecimalFormat; import java.util.Properties; public class HelloWorld { // 決まり文句 (ドライバクラス) final private static String PostgresJDBCDriver = "org.postgresql.Driver"; final private static String MySQLJDBCDriver = "org.gjt.mm.mysql.Driver"; final private static String JavaDBJDBCDriver = "org.apache.derby.jdbc.EmbeddedDriver"; final private static String HiRDBDriver = "JP.co.Hitachi.soft.HiRDB.JDBC.PrdbDriver"; // 下記の変数を正しく設定する // DBNAME, DBDIR, USER, PASS, JDBCDriver, DBURL // PostgreSQL 用デフォルト // Eclipse で PostgreSQL を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく. // WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」 // その後インポートすべきファイルとして,次のファイルを指定 // C:\Program Files\psqlJDBC\postgresql-8.3-603.jdbc4.jar // final private static String DBNAME = "testdb"; // Database Name // final private static String USER = "testuser"; // user name for DB. // final private static String PASS = "hoge$#34hoge5"; // password for DB. // final private static String JDBCDriver = PostgresJDBCDriver; // final private static String DBURL = "jdbc:postgresql://localhost/" + DBNAME; // MySQL 用デフォルト // Eclipse で MySQL を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく. // https://dev.mysql.com/downloads/connector/ から,Connector/J をダウンロード // c:\Program Files\Java\mysql-connector-java-5.1.7\ に置く. // WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」 // その後インポートすべきファイルとして,次のファイルを指定 // c:\Program Files\Java\mysql-connector-java-5.1.7\mysql-connector-java-5.1.7-bin.jar を追加 final private static String DBNAME = "testdb"; // Database Name final private static String USER = "testuser"; // user name for DB. final private static String PASS = "hoge$#34hoge5"; // password for DB. final private static String JDBCDriver = MySQLJDBCDriver; final private static String DBURL = "jdbc:mysql://localhost/" + DBNAME; // JavaDB用デフォルト // final private static String DBNAME = "dbdir;create=true"; // Java DB の場合は,Java DB データベースディレクトリ(相対) // final private static String DBDIR = "C:\\Program Files\\eclipse3.5\\eclipse\\"; // データベースが存在するディレクトリ 申し訳ありません.前回の続きから,途切れることなく最後まで表示いたします. // DTP, DBViewer などを使ってデータベースを生成した場合は Eclipse インストールディレクトリ // ij などを使ってデータベースを生成した場合は,c:\\<ワークスペース>\\<プロジェクト名> // final private static String USER = ""; // user name for DB. Java DB (Derby) の場合は空 // final private static String PASS = ""; // password for DB. Java DB (Derby) の場合は空 // final private static String JDBCDriver = JavaDBJDBCDriver; // final private static String DBURL = "jdbc:derby:" + DBDIR + DBNAME; // HiRDB用デフォルト // Eclipse で HiRDB を使いたいときは,次の手順で,WebContent\WEB-INF\lib にインポートしておく. // WebContent\WEB-INF\lib を右クリック.「一般」→「ファイルシステム」 // その後インポートすべきファイルとして,次のファイルを指定 // C:\win32app\hitachi\hirdb_s\CLIENT\UTL\pdjdbc.jar // ユーザ名,パスワード: C:/windows/HiRDB.iniのPDUSER の値を調べておく // final private static String USER = "ユーザ名"; // user name for HiRDB. see C:/windows/HiRDB.ini // final private static String PASS = "パスワード"; // password for HiRDB. see C:/windows/HiRDB.ini // final private static String JDBCDriver = HiRDBDriver; // final private static String HiRDBServerName = "hitachi-664320D"; // HiRDB サーバのコンピュータ名 // final private static String DBURL = "jdbc:hitachi:PrdbDrive://DBID=22200,DBHOST=" + HiRDBServerName + ",ENCODELANG=MS932"; // 'DBID=22200' is in "conf\pdsys"; // この先は決まり文句 private static Statement stmt = null; // 問い合わせ結果を System.out.print で,画面に出力 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 { try { connect( USER, PASS ); // 実行するSQL文と,出力フォーマットを記述する String updateSql = "UPDATE BLOBtest SET bytes = ? WHERE bid = ?"; PreparedStatement updateStatement = conn.prepareStatement(updateSql); //ステートメントの第1引数にバイトストリームから流し込む ByteArrayInputStream bais = new ByteArrayInputStream(bytes); updateStatement.setBinaryStream(1,bais,bytes.length); //ステートメントの第2引数に,主キー値を格納 updateStatement.setInt(2, bid); //プリペアードステートメント実行 updateStatement.executeUpdate(); bais.close(); updateStatement.close(); stmt.close(); disconnect(); } catch (Exception e) { // Error Message and Error Code System.out.print(e.toString()); if (e instanceof SQLException) { System.out.println("Error Code:" + ((SQLException)e).getErrorCode()); } // Print Stack Trace e.printStackTrace(); if (conn != null) { conn.rollback(); conn.close(); } } } public static void printTable() throws SQLException { try { connect( USER, PASS ); // 実行するSQL文と,出力フォーマットを記述する ResultSet rs = execute( "select * from BLOBtest" );; DecimalFormat dformat = new DecimalFormat ("#,###"); while(rs.next()){ int bid = rs.getInt("bid"); String bytes = rs.getString("bytes"); // bid を表示 System.out.printf( dformat.format( bid ) + ":" ); // 空のときは (null) と表示しておしまい if ( bytes == null ) { System.out.println( "(null)" ); } else if ( bytes.isEmpty() ) { System.out.println( "(empty)" ); } else { System.out.printf( "(%1$2x)", bytes.length() ); for( int i=0; i
- ソースを保存
ソースコードは「ファイル」メニューの「保管」を選択するか,CTRL+Sのショートカットキーで保存することができる. 保存操作を行うと,自動的にコンパイルが実行される.
コンパイル処理中にエラーや警告が発生した場合は, Eclipseの問題ビューに詳細が表示されるため,必ず確認する.
実行
- 実行対象クラスを選択し,右クリック
プロジェクト・エクスプローラーには,パッケージ名の配下にクラスファイル一覧が表示される.実行対象となるクラスファイル「クラス名.java」(この場合はHelloWorld.java)を右クリックで選択する.
- 「実行」 → 「Javaアプリケーション (Java Application)」を選択
キーボードショートカットとして Alt+Shift+X を押した後,J キーを押すことでも実行が可能である.
- 実行結果は以下のように表示される.
1 apple 50円 2 orange 20円 3 strawberry 100円 4 watermelon 150円 5 melon 200円 6 banana 100円
- 実行時に「接続できない」というエラーが発生した場合の対処方法:
他のプロセスによる接続保持が考えられるため,Eclipse を再起動してから再度実行を試みる.
問題が解決しない場合は,DBNAME,DBDIR などの環境変数の設定値を慎重に確認する.
(参考情報)
Eclipseでデータベースの内容を効率的に確認するには, Eclipse のデータツール・プラットホームの活用が推奨される. データツール・プラットホームの具体的な活用方法については, MySQL の利用, PostgreSQL の利用, Java DB (Derby)のそれぞれについて,専用ページで詳細に解説している.
参考Webページ: http://allabout.co.jp/internet/java/closeup/CU20070119A/index4.htm
参考Webページ: http://www.atmarkit.co.jp/fjava/javafaq/jdbc/jdbc01.html