MySQL の BLOB (Binary Large Object) の活用方法 - Java と Eclipse による実装ガイド

このページでは,MySQL の活用において,BLOB (Binary Large Object) を効率的に処理するJavaプログラムの実装方法を,詳細な解説と実践的なサンプルコードを用いて説明する.開発環境としてEclipseを使用する.

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 実行結果の効率的な処理には,最適化されたプログラム構造の設計が不可欠である.

必要なソフトウェア環境

事前設定と環境構成

設定内容について,このWebページで紹介するプログラムは,以下の設定を前提としている. 環境が異なる場合は,必要に応じてプログラムコードを適切に修正する.

データベース名および MySQL アクセス用の一般ユーザアカウント(ユーザ名とパスワード)の 設定は以下の通りである.

MySQL の利用における重要な設定項目は以下の通りである.

テスト用データベースの構築

テスト環境として,以下の SQL コマンドを実行し,BLOBtest テーブルを作成してデータを格納する.

create table BLOBtest (
          bid INTEGER primary key not null,
          bytes BLOB
);

* SQL の効率的な実行には,Eclipse データツール・プラットフォームの活用を推奨する. 詳細な使用方法は専用ページで解説している.

Eclipse における JDBC プログラム実装手順

Eclipse の事前設定とクラス定義の準備

Eclipse のプロジェクト構成を以下のように設定する. 既存の同名プロジェクトがある場合は,プロジェクト名を適切に変更する.

  1. プロジェクトとパッケージの作成手順の詳細は,Eclipse における JDBC プログラミングガイドを参照のこと.
  2. 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 が正しく作成されていることを確認する.

  1. エディタでクラス 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();
    
    1. SQLクエリの実行結果は変数 rs に格納される.
    2. rs には複数のレコード(行)データが含まれており,これらを適切なJavaの単純型変数に変換する必要がある.
    3. while(rs.next() によるイテレーション処理により,rs 内の各レコード(行)を順次処理する.
    4. 各レコード(行)は複数の属性値で構成され,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
    
  2. ソースを保存

    ソースコードは「ファイル」メニューの「保管」を選択するか,CTRL+Sのショートカットキーで保存することができる. 保存操作を行うと,自動的にコンパイルが実行される.

    コンパイル処理中にエラーや警告が発生した場合は, Eclipseの問題ビューに詳細が表示されるため,必ず確認する.

実行

  1. 実行対象クラスを選択し,右クリック

    プロジェクト・エクスプローラーには,パッケージ名の配下にクラスファイル一覧が表示される.実行対象となるクラスファイル「クラス名.java」(この場合はHelloWorld.java)右クリックで選択する.

  2. 実行」 → 「Javaアプリケーション (Java Application)」を選択

    キーボードショートカットとして Alt+Shift+X を押した後,J キーを押すことでも実行が可能である.

  3. 実行結果は以下のように表示される.

    1 apple 50円
    2 orange 20円
    3 strawberry 100円
    4 watermelon 150円
    5 melon 200円
    6 banana 100円
    
  4. 実行時に「接続できない」というエラーが発生した場合の対処方法:

    他のプロセスによる接続保持が考えられるため,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