パフォーマンスを意識した設計/実装テクニックJavaのDBアクセスを極める(6)(3/3 ページ)

» 2005年07月13日 00時00分 公開
[宮本和洋 著, 安間裕 監修アクセンチュア・テクノロジー・ソリューションズ]
前のページへ 1|2|3       

オブジェクト生成のチューニング

 頻繁なオブジェクトの生成および破棄もパフォーマンスの劣化を引き起こす原因になります。バッチ処理を使用すればデータベース・サーバとの通信の回数を削減できますが、挿入したデータをすぐに更新したいなどの業務的な要件によりバッチ処理を使用できない場合、PreparedStatementの生成と破棄の回数が多くなって、オブジェクトの生成と破棄の繰り返しによるコストが無視できないものになってしまいます。

 そこでPreparedStatementをキャッシュすることで、オブジェクトの生成と破棄の回数を減らす工夫をします。

import java.util.*;
import java.sql.*;
public class CreatePrepareStatement {
    // PreparedStatementを格納するキャッシュ
    private HashMap pstmtCache;
    private static CreatePrepareStatement instance;
    private Connection con;
    // Singletonパターンを使用するため
    // コンストラクタはprivateにする
    private CreatePrepareStatement()
    {
        pstmtCache = new HashMap();
    }
    public synchronized static CreatePrepareStatement getInstance()
    {
        if(instance == null)
        {
            instance = new CreatePrepareStatement();
        }
        return instance;
    }
    public PreparedStatement getPrepareStatement(String sqlQuery)
    {
        PreparedStatement pstmt = null;
        try{
            // キャッシュ上にPreparedStatementが存在している場合
            if(pstmtCache.containsKey(sqlQuery))
            {
                // キャッシュより取得
                pstmt = (PreparedStatement)pstmtCache.get(sqlQuery);
            }
            // キャッシュ上に存在しない場合は新規に生成し、
            // キャッシュに格納する
            else
            {
                pstmt = con.prepareStatement(sqlQuery);
                pstmtCache.put(sqlQuery, pstmt);
            }
        }
        catch(SQLException se)
        {
            System.err.println(“SQL Failed”);
            se.printStackTrace();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        return pstmt;
    }
    public void SetConnection(Connection pCon)
    {
        this.con = pCon;
    }
}
リスト3 CreatePrepareStatement.java
(2005年7月21日にコードの一部を修正しました)

 このCreatePrepareStatementクラスは単純な例として、1つのコネクションに対して1つのCreatePrepareStatementを作成することを想定しています。実際には大きなバッチ処理のプログラムを作成する際などに使用します。CreatePrepareStatementクラスのコンストラクタがprivateになっているのは、このクラスがコネクション1つにつき必ず1つだけ存在するSingletonパターンを使用しているためです。Singletonパターンを使用すれば、コネクションがクローズされないかぎりPreparedStatementのキャッシュの効果はいつまでも持続します。

Singletonパターン
クラスのインスタンスが1つしか存在しないことを保証するためのデザインパターン。コンストラクタをprivateとすることで、ほかのクラスからインスタンスを新たに生成できないようにする。

 ただし、キャッシュのサイズが大きくなりすぎないように注意してください。キャッシュしたいSQL文の種類が多い場合や繰り返し呼ばれるSQL文の種類が少ない場合などは、キャッシュの恩恵を受けることができないだけではなく、キャッシュのサイズが大きくなりすぎてプログラムの性能に影響が出てしまうことがあります。

パフォーマンス・チューニングのまとめ

 上述のように、要所にキャッシュの機能を実装することでシステムのパフォーマンスを向上させることができます。システムの設計の段階でシステムのボトルネックとなり得る部分をあらかじめ予想し、その部分にキャッシュ機能を持たせる設計をしていくとよいでしょう。

 拡張性に優れたシステムにすればパフォーマンス・チューニングをする際の影響を最小限にとどめることができますので、デザインパターンを駆使してパフォーマンス面にも拡張面にも強い設計を心掛けてください。

連載全体のまとめ

 全6回にわたって、「JavaのDBアクセスを極める」というテーマでJavaによるデータベース・アクセスの方法について連載してきました。オブジェクト指向モデルとデータベースモデルは、それぞれ設計手法としては一般的なものとして確立されてきていますが、それぞれの設計は目的とアプローチが異なっているためにインピーダンスミスマッチを引き起こしてしまいます(第1回 JavaとDBのデータモデルはナゼすれ違う?)。

 そのためO/Rマッピングというフレームワークが必要になります。O/Rマッピングのフレームワークは、ビジネスロジック・レイヤとデータベース・レイヤを分け、それぞれのレイヤはほかのレイヤを意識しない構造にすることができるため、効率よくそれぞれのレイヤの実装をしていくことができるようになります(第2回 O/Rマッピングで失敗しない分析・設計のポイント)。

 システムの設計の際には、インピーダンスミスマッチを引き起こす原因とそれにより引き起こされる問題について理解する必要があります。OOA(Object Oriented Analysis)とDOA(Data Oriented Approach)それぞれのアプローチの違いについての現実的な落としどころを探るためには、問題点を明確に把握したうえで設計段階で「永続化処理の分析・設計プロセス」を規定することが重要になります(第3回 OOAとDOAを併用した最適な分析/設計パターン)。

 永続化の手段としてRDBだけではなく、OODB、XMLDBも視野に入れるべきでしょう。RDB/OODB/XMLDBそれぞれの特徴をよく理解して、システムに最適なDBMSを選択するようにするべきです(第4回 RDB/OODB/XMLDBで比較する永続化設計)。

 OOAとDOAのインピーダンスミスマッチは、DAOパターンとFacadeパターンを使用することにより、ビジネスロジック・レイヤとデータベース・レイヤを切り離して考えられるようになります。こうすることで永続化処理の実装時における各レイヤ間の依存関係を最小限にできます(第5回 デザインパターンを利用したDBアクセスの実装)。

 永続化処理を実装するうえでは、まずデザインパターンを用いてシステムの拡張に対する柔軟性やボトルネックとなり得る部分を考慮した設計を行い、実装においてもパフォーマンスを考慮して実装をしていきます(第6回 パフォーマンスを意識した実装テクニック)。

連載の終わりに

 読者の皆さま、全6回にわたる当連載をお読みいただきありがとうございました。システムの構築を「なりわい」とし、日々、いろいろな課題に取り組んでいらっしゃる方々に、同じ立場の人間として、少しでも「書籍やベンダのマニュアルには記述されていない」「現場感のある」「もの作りの専門家としての」視点を執筆者一同、心掛けてきたつもりです。技術者の方々が「使用者の方々に喜んでいただけるシステム」を構築するための一助になれば幸いです。(連載完結)

アクセンチュア・テクノロジーソリューションズ
代表取締役社長
安間 裕

筆者紹介

アクセンチュア・テクノロジー・ソリューションズ

アクセンチュアから生まれた、企業改革のためのシステム開発を手掛けるエンジニア集団。安間裕が代表取締役社長を務める。諏訪勇紀はJavaに精通しSI上流での分析/設計を得意とするシニア・システム・アナリスト。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。