- PR -

Connectionオブジェクトはどう持つべき?

1
投稿者投稿内容
ナカムラ
会議室デビュー日: 2004/03/21
投稿数: 12
投稿日時: 2004-03-21 21:52
こんばんは。中村と申します。

表題の件ですが、"private"で持つべきか、"private static"で持つべきか迷っております。
まずはソースを見てください。


public class DBManager {

  // インスタンス変数
  private Connection _connection = null; // DBコネクション
  private static DBManager _instance = new DBManager(); // 自インスタンス
  …

  /**
   * コンストラクタ
   * <br>
   */
  private DBManager()
  {
    // DBセッションの取得
    this.connectDb( "jdbcDriver",
            "dbUrl",
            "dbUser",
            "dbPassword" );
  }
  …

  /**
   * 自インスタンスを取得
   * <br>
   *
   * @return 自インスタンス
   */
  public static DBManager getInstance()
  {
    return _instance;
  }
  …

  /**
   * DBセッションの取得
   * <br>
   *
   * @param String jdbcDriver
   * @param String dbUrl
   * @param String dbUser
   * @param String dbPassword
   */
  private void connectDb( String jdbcDriver,
              String dbUrl,
              String dbUser,
              String dbPassword )
  {
    try{
     // JDBCドライバのロード
     Driver driver = ( Driver )(Class.forName( "jdbcDriver" ).newInstance() );
     DriverManager.registerDriver( driver );
    }
    catch( Exception exception ){}

    try{
      this._connection = DriverManager.getConnection( dbUrl,
                              dbUser,
                              dbPassword );
    }
    catch( SQLException sqlException ){}
  }
}

このクラスは、VMのクラスロード時に自インスタンスを取得し、
getInstance()で(唯一の)インスタンスを取得するようにしています。

で、気になっている点なのですが、コンストラクタ内でコネクションをはりにいってるのですが、
このやり方どうなんでしょうか?(自分で作っておいてなんですが…)

getInstatnce()内で

if( _connection == null )
{
    // DBセッションの取得
    this.connectDb( "jdbcDriver",
            "dbUrl",
            "dbUser",
            "dbPassword" );
}

という方法もあると思うのですが、この場合だとインスタンス変数のConnectionオブジェクトを"private static"で持つべき必要があると思います。

現在はシングルで動かしておりますので、それ程気にする必要はないのでしょうが、
勉強のためにマルチにもちゃんと対応したクラスを設計したいと思い。

皆様のお考えをお聞かせ願えないでしょうか?
よろしくお願いいたします。

ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2004-03-21 22:13
staticで持ってしまうとSingletonパターンを使用している意味が無くなるので、
"private"で宣言した方が良いと思います。

DBManagerインスタンスが2つ必要になった場合、static変数だと対応出来ませんので。
(他にも色々あります)

[追記]
※削除
[追々記]
勘違いでした...

[ メッセージ編集済み 編集者: ぽん 編集日時 2004-03-21 22:50 ]
ナカムラ
会議室デビュー日: 2004/03/21
投稿数: 12
投稿日時: 2004-03-21 22:28
こんばんは。中村です。

ご返答どうもありがとうございます。

コンストラクタ内でコネクションをつなぐのは懸念しなくてもよろしいのでしょうか?
よろしくお願いいたします。
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2004-03-21 22:38
引用:

未記入さんの書き込み (2004-03-21 22:28) より:

コンストラクタ内でコネクションをつなぐのは懸念しなくてもよろしいのでしょうか?


う〜ん・・・特に問題は無いと思いますが。

取り合えず私に分かるのは、例外をキャッチして何もしないのはやめた方が良いですよ、
最低でもエラーメッセージは出力しないと、後で泣きを見ます。

[追記]
問題ありました
コンストラクタ内でコネクション接続するなら、
例外キャッチしたら駄目ですね、失礼。
(キャッチするなら、もう一度例外をスロー)

[ メッセージ編集済み 編集者: ぽん 編集日時 2004-03-22 09:48 ]
ナカムラ
会議室デビュー日: 2004/03/21
投稿数: 12
投稿日時: 2004-03-21 22:52
こんばんは。中村です。

紙面(?)の都合上、割愛させていただきました。
どうありがとうございます。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2004-03-22 00:59
staticで持つべきではないですね。
staticでConnectionを持ってしまうと、
DBManagerがSingletonでなくなった場合でも、
DBManagerのインスタンスではなく、クラスがConnectionを持っているので、
Connectionは1つしかもてません。

ちなみに、上記ソースでは
コンストラクタでConnectionの生成に失敗すると、
二度とConnectionを生成できません。
また、生成できても長時間放置によってConnectionがなくなるケースもあるので、
Connectionを使いまわすのもいいですが、
Connection死亡時にConnectionを再生成する機能をつける必要があります。

Webなら独自にConnection生成を行うユーティリティクラスを実装するより
APサーバに実装されたコネクションプーリングを使用するための
ユーティリティクラスを実装したほうがよいかと思います。
ナカムラ
会議室デビュー日: 2004/03/21
投稿数: 12
投稿日時: 2004-03-22 18:47
こんばんは。中村です。

ご教授ありがとうございます。

今のところWebは意識しておりませんので、
自分でプーリングするUtilityクラスを作ってみようと思います。

またわからないことがありましたらよろしくお願いしたします。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2004-03-23 11:16
自作にこだわらないなら、Jakarta Commons DBCPはいかがですか?

http://jakarta.apache.org/commons/dbcp/
1

スキルアップ/キャリアアップ(JOB@IT)