Apache Derby を使用した開発 ― 3 連単を当てる: Apache Derby を使用した Java データベース開発、パート 3

データを変更する

Java™ プログラムから Apache Derby データベースを変更する方法を学んでください。今回は連載の前の 2 回の記事を基に、Javaアプリケーション内から Apache Derby データベースのテーブルを作成および削除する方法、データを挿入、更新、削除する方法を説明します。また、JDBCの Statement および PreparedStatement クラスの使用方法、そして SQL バッチによってパフォーマンスを改善する方法も取り上げます。

Robert Brunner, NCSA Research Scientist, Assistant Professor of Astronomy, University of Illinois, Urbana-Champaign

Robert J. BrunnerRobert J. Brunnerは、米国立スーパー・コンピューター応用研究所に科学者として勤務するかたわら、イリノイ大学アーバナ・シャンペーン校で天文学の助教授を務めています。何冊かの著作と、さまざまな分野にわたる数多くの記事や解説書を発表しています。連絡先はrb@ncsa.uiuc.eduです。



2007年 2月 20日

はじめに

この連載の前回の記事 「Apache Derbyを使用した開発 -- 3連単を当てる: Apache Derby を使用した Java データベース開発、パート 2」(developerWorks、2007年1月) では、Apache Derby データベースで Java の Statement オブジェクトを使って SQL の SELECT クエリーを実行する方法を紹介しました。クエリーは基本的に、そのクエリーを満たす行のセットを返します。そのため、Statement オブジェクトの executeQuery メソッドを使用してクエリーを実行すると、Java の ResultSet オブジェクトとして行のセットが返されるというわけです。

一方、SQL データ定義言語 (DDL) コマンドをはじめとする多くの SQL ステートメントは、行のセットを返す代わりに、テーブルの作成、行の挿入、更新、削除などのアクションを実行します。これらの操作によって返されるのは、アクションの結果(挿入または削除された行数など) あるいはエラーの可能性をエンコードした整数値です。リスト 1 に示すように、SQL DDL 操作の場合、操作が成功した場合の戻り値はゼロとなります。SQLDDL ステートメントを Apache Derby データベースで使用する方法については、「Apache Derbyを使用した開発 -- 3連単を当てる」シリーズの 3 回目の記事シリーズの 3 回目の記事で詳しく説明しています。

リスト 1. SQL DDL ステートメントの処理
...
public class BuildSchema {
...
    private static final String dropProductsSQL = "DROP TABLE bigdog.products" ;

    private static final String createProductsSQL = 
        "CREATE TABLE bigdog.products(" +
            "itemNumber INT NOT NULL," +
            "price DECIMAL(5, 2)," +
            "stockDate DATE," +
            "description VARCHAR(40))" ;

    private static final String productsQuerySQL = 
        "SELECTitemNumber, price, stockDate, description FROM bigdog.products " ;       
 
    static int processStatement(String sql) throws SQLException {
                
        Statement stmt = con.createStatement() ;
        int count = stmt.executeUpdate(sql) ;

        stmt.close() ;
                
        return(count) ;
    }
...
    public static void main(String[] args) {

        try {
            Class.forName(driver) ;
            con = DriverManager.getConnection(url);
...
            processStatement(dropProductsSQL) ;
            processStatement(createProductsSQL) ;

            doProductsQuery(productsQuerySQL) ;

        } catch (SQLException se) {
            printSQLException(se) ;
        }
...

この記事で以降に記載する Java コードと同じく、上記の例は前回の記事に記載した ThirdQuery の例に基づいているので、ここでは部分的なコードだけをリストします (完全なコードは、「ダウンロード」セクションで圧縮ファイルとして入手できます)。上記の例では、まずいくつかの Java String オブジェクトを定義しています。これらのオブジェクトに含まれるのは、この連載全体をとおして使用している bigdog.products テーブルを削除および作成するための SQL コードです。次に定義している processStatement という新しいメソッドは、指定された SQL ステートメントをStatement オブジェクトの executeUpdate メソッドを使用して処理します。

processStatement メソッドを使用できるのは、SQL DDL や SQL の INSERTUPDATEDELETE 操作など、データを返さない SQL 操作だけです。このメソッドは SQL を Apache Derby データベースに送信し、データベースでSQL が処理されると整数値が返されます。SQL DDL 操作の場合、戻り値はゼロなので、この初歩的な main メソッドの例では無視しても構いませんが、より複雑な実際のスキーマでデータを操作する場合には、戻り値を確認してエラーの条件がないようにする必要があります。

この記事に記載する Java プログラムを実行するには、空の作業環境が必要です。それには、リスト 2 に表示したコマンドに従ってこのプロセスを実行してください。前の記事で作成した既存のテスト・データベースがある場合は、それを使用しても構いません。

リスト 2. Java のデータベース・スキーマ変更
rb$ cd derbyWork
rb$ unzip ../derby11.zip 
Archive:  ../derby11.zip
  inflating: BuildSchema.java        
  inflating: derby.build.sql         
  inflating: FirstInsert.java        
  inflating: FirstUpdate.java        
  inflating: SecondInsert.java       
  inflating: ThirdInsert.java        
rb$ java org.apache.derby.tools.ij < derby.build.sql             
ij version 10.2
...
ij> 
rb$ javac *.java
rb$ java BuildSchema 

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------

0 rows selected

Apache Derby データベースをアップグレードしてください

お気付きかもしれませんが、リスト 2 では Apache データベースのバージョンが 10.2 になっています。データベース管理者は、新規バージョンのリリースには用心しなければなりません。どんなアップグレードでも、十分なリグレッション・テストで重要なビジネス・アプリケーションの信憑性を確認しながら、明確なマイグレーション手順に従って慎重に行う必要があります。ただしこの連載で使用する場合は、思い切ってアップグレードしてください。この新規バージョンには多数の機能とともにバグ修正も追加されているので、アップグレードを容易に決断できます。

上記の手順は至って簡単です。

  1. 空の作業ディレクトリーを作成し、この新規ディレクトリーにサンプル・コードを解凍します。
  2. Apache Derby の ij ツールを使用して、サンプル・コードに含まれている Apache Derby スクリプト・ファイルを実行します。
  3. この記事付属のすべての Java コードをコンパイルし、 BuildSchema プログラムを実行します。

サンプル出力を見るとわかるように、BuildSchema クラスは bigdog.products テーブルを削除してからもう一度作り直すため、まったく新規のテーブルに新しいデータを挿入できます。


データ変更のステートメント

前の例では CREATEDROP などの SQL DDL ステートメントで bigdog スキーマを変更しました。一方、リスト 3 に示すように SQL の INSERT 文を使用すると、同じようなプロセスで新しい行を挿入できます。

リスト 3. SQL INSERT 文の処理
...
public class FirstInsert {
...
    private static final String insertProductsSQL = 
        "INSERT INTO bigdog.products(itemNumber, price, stockDate, description) VALUES" ;

    private static final String[] productsData = 
        {"(1, 19.95, '2006-03-31', 'Hooded sweatshirt')",
         "(2, 99.99, '2006-03-29', 'Beach umbrella')",
         "(3, 0.99, '2006-02-28', '')",
         "(4, 29.95, '2006-02-10', 'Male bathing suit, blue')",
         "(5, 49.95, '2006-02-20', 'Female bathing suit, one piece, aqua')",
         "(6, 9.95, '2006-01-15', 'Child sand toy set')",
         "(7, 24.95, '2005-12-20', 'White beach towel')",
         "(8, 32.95, '2005-12-22', 'Blue-stripe beach towel')",
         "(9, 12.95, '2006-03-12', 'Flip-flop')",
         "(10, 34.95, '2006-01-24', 'Open-toed sandal')"} ;

    private static final String productsQuerySQL = 
        "SELECT itemNumber, price, stockDate, description FROM bigdog.products " ;       
...
    public static void main(String[] args) {
...
            int numRows = 0 ;

            for(String product: productsData){
                numRows += processStatement(insertProductsSQL + product) ;
            }

            System.out.println("\n" + numRows + 
                " rows inserted into bigdog.products table.") ;

            doProductsQuery(productsQuerySQL) ;
...

明示的クエリー: ベスト・プラクティス

リスト 3 の SQL INSERT 文では、列名が明示的にリストされています (itemNumberprice など)。列名は省略することもできますが、それはお勧めしません。省略すると、他の誰かが列の名前を変更したり、列を追加あるいは削除するなどしてスキーマを不意に変更した場合、コードが予期せぬ、誰も気付かずに潜在するエラーになってしまう可能性があるからです。列の名前とその順序を明示的にリストすることによって、このようなエラーが発生するリスクを最小限に抑えることができます。

上記の FirstInsert Java プログラムは、SQL DDL ステートメントを SQL の INSERT 文に置き換え、processStatement メソッドを呼び出す前に 2 つの Java String オブジェクトを追加して、該当する製品データが含まれるように変更されています。この場合、データの各行は個別に挿入されるので、processStatement メソッドによって返される行カウントを累積してデータベースに挿入された行の合計数を判断します。

この操作で bigdog.products テーブルに挿入する 10 行は、連載の以前の記事で追加した行と同じですが、今回は一度に 1 行ずつ挿入しています。すべてのデータ (この例の場合は 10 行) を一度に挿入する 1 つの大きなストリングを作成することも可能ですが、その方法は以下の2 つの理由から良い考えとは言えません。

  • 一度に 1 つの行を挿入することによって、データベース内のデータをよりきめ細かなレベルで制御できます。つまり、操作対象が常に 1 行だけであれば、行の挿入に失敗した場合、問題を突き止めるのが簡単になります。
  • 多数の行を挿入する単一の大きな Java String を使うとコードが見苦しくなり、コードの管理も難しくなります。このように複数の Java String オブジェクトをまとめて追加するのは推奨されない事例なので、代わりに StringBuffer を使用する必要があります。だたし、この記事では説明のために、上記のより単純な方法に従います

この Java コードを実行するには、FirstInsert プログラムを実行します。プログラムを実行すると、bigdog.products テーブルに新しく 10 行が入力され、リスト 4 のように表示されます。

リスト 4. Java コードによるデータの挿入
rb$ java FirstInsert 

10 rows inserted into bigdog.products table.

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------
1          |19.95   |2006-03-31|Hooded sweatshirt                       
2          |99.99   |2006-03-29|Beach umbrella                          
3          |0.99    |2006-02-28|                                        
4          |29.95   |2006-02-10|Male bathing suit, blue                 
5          |49.95   |2006-02-20|Female bathing suit, one piece, aqua    
6          |9.95    |2006-01-15|Child sand toy set                      
7          |24.95   |2005-12-20|White beach towel                       
8          |32.95   |2005-12-22|Blue-stripe beach towel                 
9          |12.95   |2006-03-12|Flip-flop                               
10         |34.95   |2006-01-24|Open-toed sandal                        

10 rows selected

準備済みステートメント

前のセクションでは、該当する SQL の INSERT 文が含まれる Java String を作成して、Apache Derby データベースに 10 行のデータを挿入しました。この方法は機能するとは言え、最善の方法ではありません。JavaStatement オブジェクトの executeUpdate メソッドを呼び出すには、毎回新しい静的 INSERT 文を作成しなければならないためです。

それよりも効率的なのが、基本となる INSERT 文をデータベースに送信してから必要に応じて、新しい行ごとに関連データを渡すという方法です。この方法では、Java コンパイラーが Java関数を処理するのと同じ方法で、データベースに SQL ステートメントを準備させることができます。同じく、この準備済み SQL ステートメントに新しいパラメーターを渡して処理することもできます。この方法はパフォーマンスの大幅な改善につながる可能性があるため、JDBC仕様では異なる入力パラメーターで SQL 操作を何度も実行できる PreparedStatement クラスを提供しています。

動的 SQL INSERT 文

PreparedStatementStatement とでは機能が異なるため、その使用方法も異なります。PreparedStatement を使用する場合はまず、入力パラメーターが提供される場所を示す疑問符 (?) を使って、基本となる SQL の INSERT 文を変更する必要があります。例えば、 VALUES(?, ?, ?, ?) は 4 つの入力パラメーターが提供されると SQL INSERT 文のVALUES 節が完成することを示します。この変更した StringConnection オブジェクトの prepareStatement メソッドへの入力として渡すと、Apache Derby データベースが処理速度を上げるために SQL をプリコンパイルします。

2 つ目の違いは、入力パラメーターのそれぞれに値を提供しなければならないということです。そのため、入力パラメーターごとに setXXXメソッドを呼び出します。このクラスのメソッドで重要なのは、以下の 2 つの点です。

  • XXXはデータベースに送信するパラメーターのデータ型に置き換わります。例えば、setInt は整数型を送信すること、setDateDate オブジェクトを送信することを示しています。
  • メソッドが使用するパラメーターは、入力パラメーターの序数と実際に使用する値の 2 つです。設定対象の入力パラメーターを示す序数値を組み込むことによって、入力パラメーターを特定の順序で設定する必要がなくなります。

PreparedStatement の使用方法は複雑そうに聞こえるかもしれませんが、実際はリスト 5 に示すように非常に簡単です。

リスト 5. SQL INSERT 操作での準備済みステートメントの使用
...
public class SecondInsert {
...
    private static final String insertProductsSQL = 
        "INSERT INTO bigdog.products(itemNumber, price, stockDate, description) " + 
            "VALUES(?, ?, ?, ?)" ;

    private static final int[] itemNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ;

    private static final BigDecimal[] prices = 
        {new BigDecimal(19.95), new BigDecimal(99.99), new BigDecimal(0.99), 
         new BigDecimal(29.95), new BigDecimal(49.95), new BigDecimal(9.95), 
         new BigDecimal(24.95), new BigDecimal(32.95), 
         new BigDecimal(12.95), new BigDecimal(34.95)} ;

    private static final Date[] dates = 
        {Date.valueOf("2006-03-31"), Date.valueOf("2006-03-29"), 
         Date.valueOf("2006-02-28"), Date.valueOf("2006-02-10"), 
         Date.valueOf("2006-02-20"), Date.valueOf("2006-01-15"),
         Date.valueOf("2005-12-20"), Date.valueOf("2005-12-22"), 
         Date.valueOf("2006-03-12"), Date.valueOf("2006-01-24")} ;

    private static final String[] descriptions = 
        {"Hooded sweatshirt", "Beach umbrella", "", "Male bathing suit, blue", 
         "Female bathing suit, one piece, aqua", "Child sand toy set", 
         "White beach towel", "Blue-stripe beach towel", "Flip-flop", 
         "Open-toed sandal"} ;

    private static final String productsQuerySQL = 
        "SELECT itemNumber, price, stockDate, description FROM bigdog.products " ;       
...
    static void insertData(String sql) throws SQLException {

        int numRows = 0 ;

        PreparedStatement stmt = con.prepareStatement(sql) ;

        for(int itemNumber: itemNumbers){
            stmt.setInt(1, itemNumbers[itemNumber - 1]) ;
            stmt.setBigDecimal(2, prices[itemNumber - 1]) ;
            stmt.setDate(3, dates[itemNumber - 1]) ;
            stmt.setString(4, descriptions[itemNumber - 1]) ;

            numRows += stmt.executeUpdate() ;
        }

        System.out.println("\n" + numRows + 
            " rows inserted into bigdog.products table.") ;

        stmt.close() ;
    }

    public static void main(String[] args) {
...
            insertData(insertProductsSQL) ;
            doProductsQuery(productsQuerySQL) ;
...

上記のサンプル・コードではまず、挿入するデータが含まれる Java 配列を定義しています。説明用としてはこれで役に立ちますが、実動環境では、このデータをファイルから読み取るか、あるいは計算結果やユーザーの入力から取得することになります。その他の変更点は、基本的にStatement オブジェクトを使ったコードから PreparedStatement オブジェクトを使ったコードへの変更に伴うものです。この変更には以下が含まれます。

  • PreparedStatement オブジェクトの作成
  • 関連入力パラメーター (Java の intBigDecimalDate、および String など) の設定
  • executeUpdate メソッドによる INSERT 文の実行

このコンセプトがどのように機能するかを見るため、まずは既存の bigdog.productsテーブルをクリアしてください。リスト 6 に示すように、BuildSchema プログラムを実行してから SecondInsert プログラムを実行すると簡単にテーブルをクリアできます (以下のコード・リストでは、スペースを節約するため出力を簡略化しています)。

リスト 6. Java 準備済み INSERT 文の実行
rb$ java BuildSchema

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------

0 rows selected
rb$ java SecondInsert

10 rows inserted into bigdog.products table.

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------
1          |19.94   |2006-03-31|Hooded sweatshirt                       
...     
10         |34.95   |2006-01-24|Open-toed sandal                        

10 rows selected

動的な更新と選択

Statement オブジェクトの場合と同じく、PreparedStatementオブジェクトも SQL の INSERT 操作以外の SQL 操作に使用できます。例えば、適切に設定された PreparedStatement オブジェクトを使えば、Apache Derby データベースのデータに対して選択的に UPDATE、さらに SELECT まで実行することができます。リスト 7 では、PreparedStatement を使用してbigdog.productsテーブルの行を更新してから、別の PreparedStatement を使用して更新された行を選択しています。

リスト 7. SQL INSERT および DELETE操作での準備済みステートメントの使用
...
public class FirstUpdate {
...
    private static final String updateProductsSQL = 
        "UPDATE bigdog.products SET price = price * 1.25, " + "" +
            "stockDate = CURRENT_DATE WHERE price > ?" ; 

    private static final String productsQuerySQL = 
        "SELECT itemNumber, price, stockDate, description " + 
            "FROM bigdog.products WHERE price > ?" ;    
...
    static void doProductsQuery(String sql) throws SQLException {
...
        PreparedStatement stmt = con.prepareStatement(sql) ;
        BigDecimal threshold = new BigDecimal(40.00) ;

        stmt.setBigDecimal(1, threshold) ;              

        ResultSet rs = stmt.executeQuery() ;
...
    }

    static void updateData(String sql) throws SQLException {

        PreparedStatement stmt = con.prepareStatement(sql) ;
        BigDecimal threshold = new BigDecimal(40.00) ;

        stmt.setBigDecimal(1, threshold) ;              

        int numRows = stmt.executeUpdate() ;

        System.out.println("\n" + numRows + " rows updated in bigdog.products table.") ;

        stmt.close() ;
    }

    public static void main(String[] args) {
...
            doProductsQuery(productsQuerySQL) ;                                         
            updateData(updateProductsSQL) ;
            doProductsQuery(productsQuerySQL) ;
...

FirstUpdate クラスではまず、2 つの PreparedStatement オブジェクトを作成するために渡される SQL ステートメントを 2 つ定義しています。最初の SQL UPDATE 文は、あるしきい値より大きい価格を持つ行の価格を更新するものです。2 つ目の SQL SELECT文で、あるしきい値より大きい価格を持つすべての行を選択します。この 2 つの操作を別々に行うための新規メソッドを 2 つ定義し、それからクエリーの実行、データの変更と続き、さらに同じクエリーを再実行してSQL UPDATE 操作の結果を検証しています。リスト 8 は、この Java プログラムの実行結果です。

リスト 8. Java 準備済み UPDATE および SELECT文の実行
rb$ java FirstUpdate

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------
2          |99.98   |2006-03-29|Beach umbrella                          
5          |49.95   |2006-02-20|Female bathing suit, one piece, aqua    

2 rows selected

2 rows updated in bigdog.products table.

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------
2          |124.97  |2006-11-03|Beach umbrella                          
5          |62.43   |2006-11-03|Female bathing suit, one piece, aqua    

2 rows selected

バッチ操作

PreparedStatement を使用すると、Java コードの柔軟性とパフォーマンス特性が向上しますが、それでもまだ最善の方法とは言えません。その理由は、それぞれの SQLINSERT (または他の SQL 操作) が個別のトランザクションで行われているためです。「Apache Derbyを使用した開発 -- 3連単を当てる」シリーズの 2 回目の記事で説明したように、トランザクションとは Apache Derby がデータベースの一貫性を保証するために使用する論理作業単位のことです。それぞれのトランザクションでは、すべての操作が正常に完了しない限り、すべての操作の効果が取り消されます(正式には、前のデータベース状態にロールバックします)。

executeUpdate メソッド (または executeQuery メソッド) を呼び出す時は常に、その操作は単一のトランザクションとして扱われるようになっています。そのため、複数のトランザクションを設定して完了する上でのオーバーヘッドが生じ、パフォーマンスが劣化する結果となります。それよりもいい方法は、SQLステートメントのバッチをデータベースに送信し、一括して実行することです。JDBC 仕様では、このようなパフォーマンス改善を促進するバッチ機能をサポートしています。リスト9 でその使用方法を見てください。

リスト 9. バッチ SQL INSERT 文の使用
...
public class ThirdInsert {
...
 private static final String insertProductsSQL = 
   "INSERT INTO bigdog.products(itemNumber, price, stockDate, description) " + 
       "VALUES(?, ?, ?, ?)" ;
...
 static void batchInsertData (String sql) throws SQLException {

   PreparedStatement stmt = con.prepareStatement(sql) ;

   for(int itemNumber: itemNumbers){
       stmt.setInt(1, itemNumbers[itemNumber - 1]) ;
       stmt.setBigDecimal(2, prices[itemNumber - 1]) ;
       stmt.setDate(3, dates[itemNumber - 1]) ;
       stmt.setString(4, descriptions[itemNumber - 1]) ;
       stmt.addBatch() ;
   }

   int numRows = 0 ;    
   int[] counts = stmt.executeBatch() ;

   for(int count: counts){
       numRows += count ;
   }
        
   System.out.println("\n" + numRows + 
       " rows inserted into bigdog.products table.") ;

   stmt.close() ;
 }

 public static void main(String[] args) {
...
       con.setAutoCommit(false) ;
            
       batchInsertData(insertProductsSQL) ;
       doProductsQuery(productsQuerySQL) ;
            
       con.commit() ;
            
   }catch(BatchUpdateException bue) {
       try{
          con.rollback() ;
                        
          System.err.println("Batch Update Exception: Transaction Rolled Back") ;
          printSQLException((SQLException)bue) ;
       }catch(SQLException se){
          printSQLException(se) ;
                }
...

前の 2 つの SQL INSERT サンプル・コードと ThirdInsert の大きな違いは、ThirdInsert では batchInsertData メソッドを新たに使用しているところです。このメソッドは、それぞれ完全に定義された PreparedStatementaddBatch メソッドを使ってステートメントのバッチに追加しています。このすべてのステートメントを単一のトランザクションでまとめて実行するために呼び出されるのが、executeBatchメソッドです。大量の SQL ステートメントがある場合、この方法だと Apache Derby データベースがステートメントのバッチごとに 1つのトランザクションを設定するだけで済むので、処理速度が大幅に向上します。

executeBatch メソッドは整数の配列を返します。この配列の各要素は、バッチ内の該当するステートメントによって挿入、更新、または削除された行数に対応します。上記の例では、バッチに10 のステートメントがあるため、配列には 10 の整数が含まれています。これらの整数を繰り返し処理することで、バッチ内で変更された行の合計数を取得します。これは重要な点です。つまい、SQLバッチに含められるのは明らかに、CREATEDROPINSERTUPDATEDELETE 操作などの SQL データ変更コマンドだけだということを示しています。単一の更新カウントしか返さない SELECT クエリーなどの SQL コマンドをバッチに含めようとすると、executeBatch メソッドが例外をスローします。

batchInsertData メソッドを呼び出すには、main メソッドに以下の変更も必要になります。

  1. バッチを設定する前に、現行データベース接続の autocommit モードを無効にします。これは、何かがうまくいかない場合、バッチに含まれる SQL 操作が意図に反して自動的にデータベースに適用されないようにするためです。
  2. バッチが正常に処理された後の明示的コミット操作を追加します。
  3. バッチの処理中にデータベースに問題が発生した場合にスローされる BatchUpdateException に対する例外ハンドラーを追加します。

この単純な例では、現行トランザクションをロールバックしてバッチ内で行われた可能性のあるすべてのデータベース変更を取り消していますが、実動環境ではBatchUpdateException の中でgetUpdateCountメソッドを呼び出すことができます。このメソッドは、バッチ内のあらゆる SQL 操作が成功したか失敗したかを示す値が含まれる配列を返すので、問題の診断と修正が容易になります。

バッチ挿入の例をテストするには、リスト 10 に示すようにまず bigdog.products テーブルを空にしてから ThirdInsert プログラムを実行してください。

リスト 10. Java バッチ挿入文の実行
rb$ java BuildSchema

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------

0 rows selected
rb$ java ThirdInsert

10 rows inserted into bigdog.products table.

ITEMNUMBER |PRICE   |STOCKDATE |DESCRIPTION                             
------------------------------------------------------------------------
1          |19.94   |2006-03-31|Hooded sweatshirt                       
...
10         |34.95   |2006-01-24|Open-toed sandal                        

10 rows selected

まとめ

この記事では、Java プログラムを使って Apache Derby データベースのコンテンツを変更する方法を説明しました。まず取り上げたのは、Statement オブジェクトを使って SQL DDL および SQL INSERT 操作を実行する方法です。次に、PreparedStatement を使って、実行時に Apache Derby データベース内で動的に作成される SQL データ変更コマンドを実行する方法について説明しました。そして最後に、SQLコマンドのバッチを作成および実行して、大量の SQL データ変更コマンドを実行する Java アプリケーションのパフォーマンスを改善する方法を紹介しました。今後の記事では、これらの基本的スキルを基に、Javaアプリケーション内から一層複雑なデータベース操作を実行する方法を紹介していく予定です。


ダウンロード

内容ファイル名サイズ
Derby SQL script and Java code for this articlederby11.zip8KB

参考文献

学ぶために

製品や技術を入手するために

  • Apache Derbyをダウンロードしてください。
  • IBM ソフトウェアの試用版を使用して、次のオープン・ソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Java technology, Information Management
ArticleID=247879
ArticleTitle=Apache Derby を使用した開発 ― 3 連単を当てる: Apache Derby を使用した Java データベース開発、パート 3
publish-date=02202007