データベースコネクションプールのための API です。 {@primary Database Connection Pool API}

対話形式の概要{@primary Overview in Dialog Form}

Q: どのようにして DBCP パッケージを使えばよいのですか? {@primary Q: How do I use the DBCP package?}

A: DBCP プールにアクセスする方法は主に {@link java.sql.Driver Driver} を使う方法と {@link javax.sql.DataSource DataSource} を使う方法の2種類です。 {@link org.apache.commons.dbcp.PoolingDriver} または {@link org.apache.commons.dbcp.PoolingDataSource} のインスタンスを作成し、利用することができます。. When using one of these これらのうちいずれかのインターフェースを使用することにより一般的な方法で JDBC オブジェクトを使用することができます。 {@link java.sql.Connection} を閉じる場合には単純にプールに対してこれを返してください。 {@primary A: There are two primary ways to access the DBCP pool, as a {@link java.sql.Driver Driver}, or as a {@link javax.sql.DataSource DataSource}. You'll want to create an instance of {@link org.apache.commons.dbcp.PoolingDriver} or {@link org.apache.commons.dbcp.PoolingDataSource}. When using one of these interfaces, you can just use your JDBC objects the way you normally would. Closing a {@link java.sql.Connection} will simply return it to its pool.}

Q: しかし {@link org.apache.commons.dbcp.PoolingDriver PoolingDriver} と {@link org.apache.commons.dbcp.PoolingDataSource PoolingDataSource} は両方とも {@link org.apache.commons.pool.ObjectPool ObjectPool} を入力されることが想定されています。 これはどこから持ってくればよいのでしょうか? {@primary Q: But {@link org.apache.commons.dbcp.PoolingDriver PoolingDriver} and {@link org.apache.commons.dbcp.PoolingDataSource PoolingDataSource} both expect an {@link org.apache.commons.pool.ObjectPool ObjectPool} as an input. Where do I get one of those?}

A: {@link org.apache.commons.pool.ObjectPool ObjectPool} インターフェースは in the {@link org.apache.commons.pool} パッケージ(Commons-Pool)で定義されています。 {@link org.apache.commons.pool.impl} パッケージには対となる実装があり、独自の実装を作成すること可能です。 {@primary A: The {@link org.apache.commons.pool.ObjectPool ObjectPool} interface is defined in the {@link org.apache.commons.pool} package (Commons-Pool). The {@link org.apache.commons.pool.impl} package has a couple of implementations, and you can always create your own.}

Q: OK、コネクションプーリングに適当と思われる {@link org.apache.commons.pool.ObjectPool ObjectPool} の実装を見つけることができました。 しかし、これは {@link org.apache.commons.pool.PoolableObjectFactory PoolableObjectFactory} を要求します。 これには何を使用すればよいのでしょうか? {@primary Q: Ok, I've found an {@link org.apache.commons.pool.ObjectPool ObjectPool} implementation that I think suits my connection pooling needs. But it wants a {@link org.apache.commons.pool.PoolableObjectFactory PoolableObjectFactory}. What should I use for that?}

A: DBCP パッケージはそのためのクラス {@link org.apache.commons.dbcp.PoolableConnectionFactory} を提供しています。 It implements the factory and lifecycle methods of これは {@link java.sql.Connection} のための {@link org.apache.commons.pool.PoolableObjectFactory} のファクトリとライフサイクルに関するメソッドを実装しています。 しかし実際のデータベース {@link java.sql.Connection} の生成はこれ自身ではなく {@link org.apache.commons.dbcp.ConnectionFactory} が行います。 {@link org.apache.commons.dbcp.PoolableConnectionFactory} は {@link org.apache.commons.dbcp.ConnectionFactory} にて生成された {@link java.sql.Connection} を受け取り、 プーリングの振る舞いが実装されたクラスと共にラップします。 {@primary A: The DBCP package provides a class for this purpose. It's called {@link org.apache.commons.dbcp.PoolableConnectionFactory}. It implements the factory and lifecycle methods of {@link org.apache.commons.pool.PoolableObjectFactory} for {@link java.sql.Connection}s. But it doesn't create the actual database {@link java.sql.Connection}s itself, if uses a {@link org.apache.commons.dbcp.ConnectionFactory} for that. The {@link org.apache.commons.dbcp.PoolableConnectionFactory} will take {@link java.sql.Connection}s created by the {@link org.apache.commons.dbcp.ConnectionFactory} and wrap them with classes that implement the pooling behaviour.}

いくつかの {@link org.apache.commons.dbcp.ConnectionFactory} の実装が提供されます -- 1つはコネクションの生成に {@link java.sql.DriverManager} を使用し ({@link org.apache.commons.dbcp.DriverManagerConnectionFactory})、 1つはコネクションの生成に {@link java.sql.Driver} を使用し ({@link org.apache.commons.dbcp.DriverConnectionFactory})、 もう1つはコネクションの生成に {@link javax.sql.DataSource} を使用します ({@link org.apache.commons.dbcp.DataSourceConnectionFactory})。 {@primary Several implementations of {@link org.apache.commons.dbcp.ConnectionFactory} are provided--one that uses {@link java.sql.DriverManager} to create connections ({@link org.apache.commons.dbcp.DriverManagerConnectionFactory}), one that uses a {@link java.sql.Driver} to create connections ({@link org.apache.commons.dbcp.DriverConnectionFactory}), one that uses a {@link javax.sql.DataSource} to create connections ({@link org.apache.commons.dbcp.DataSourceConnectionFactory}).}

Q: 利用する準備はできたように思いますが、もう一度通して説明してもらえますか? {@primary Q: I think I'm starting to get it, but can you walk me though it again?}

A: はい。 {@link java.sql.Connection} をプールする {@link javax.sql.DataSource} を生成する、 または、プールする {@link java.sql.Connection} を {@link java.sql.DriverManager} から取得する仮定しましょう。 この場合、 {@link org.apache.commons.dbcp.PoolingDataSource} を生成します。 {@primary A: Sure. Let's assume you want to create a {@link javax.sql.DataSource} that pools {@link java.sql.Connection}s. Let's also assume that that those pooled {@link java.sql.Connection}s should be obtained from the {@link java.sql.DriverManager}. You'll want to create a {@link org.apache.commons.dbcp.PoolingDataSource}.}

{@link org.apache.commons.dbcp.PoolingDataSource} は {@link java.sql.Connection} の生成と保持に 内部の {@link org.apache.commons.pool.ObjectPool} を使用します。 {@primary The {@link org.apache.commons.dbcp.PoolingDataSource} uses an underlying {@link org.apache.commons.pool.ObjectPool} to create and store its {@link java.sql.Connection}.}

{@link org.apache.commons.pool.ObjectPool} を生成するためには、実際に {@link java.sql.Connection} を生成する {@link org.apache.commons.pool.PoolableObjectFactory} が必要です。 これは {@link org.apache.commons.dbcp.PoolableConnectionFactory} を必要とします。 {@primary To create a {@link org.apache.commons.pool.ObjectPool}, you'll need a {@link org.apache.commons.pool.PoolableObjectFactory} that creates the actual {@link java.sql.Connection}s. That's what {@link org.apache.commons.dbcp.PoolableConnectionFactory} is for.}

{@link org.apache.commons.dbcp.PoolableConnectionFactory} を生成するためには以下の2つのものが必要です: {@primary To create the {@link org.apache.commons.dbcp.PoolableConnectionFactory}, you'll need at least two things:}

  1. 実際のデータベースの {@link java.sql.Connection} を取得することのできる {@link org.apache.commons.dbcp.ConnectionFactory} 。 {@primary A {@link org.apache.commons.dbcp.ConnectionFactory} from which the actual database {@link java.sql.Connection}s will be obtained.}
  2. {@link java.sql.Connection} を保持するために使用するファクトリを持たない空の {@link org.apache.commons.pool.ObjectPool} 。
    {@link org.apache.commons.pool.ObjectPool} を使用すれば 自動的に {@link org.apache.commons.pool.PoolableObjectFactory} のプールとして登録されます。 {@primary An empty and factory-less {@link org.apache.commons.pool.Object} in which the {@link java.sql.Connection}s will be stored.
    When you pass an {@link org.apache.commons.pool.ObjectPool} into the {@link org.apache.commons.dbcp.PoolableConnectionFactory}, it will automatically register itself as the {@link org.apache.commons.pool.PoolableObjectFactory} for that pool.}
オプションとして、各 {@link java.sql.Connection} 毎に {@link java.sql.PreparedStatement} をプールするための {@link org.apache.commons.pool.KeyedObjectPool} を生成するための {@link org.apache.commons.pool.KeyedObjectPoolFactory} を利用することもできます。 {@primary You can optionally provide a {@link org.apache.commons.pool.KeyedObjectPoolFactory} that will be used to create {@link org.apache.commons.pool.KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s for each {@link java.sql.Connection}.}

実際のコードは以下のようになります: {@primary In code, that might look like this:}

GenericObjectPool connectionPool = new GenericObjectPool(null);
DriverManagerConnectionFactory connectionFactory = new DriverConnectionFactory("jdbc:some:connect:string",null);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
PoolingDataSource dataSource = new PoolingDataSource(connectionPool);

{@link org.apache.commons.dbcp.PoolingDriver} を生成する場合も最後の行の {@link javax.sql.DataSource} のインスタンス化の部分以外は同じです。 代わりに {@link org.apache.commons.dbcp.PoolingDriver} を生成し connectionPool を登録します。 例をあげると以下のようになります: {@primary To create a {@link org.apache.commons.dbcp.PoolingDriver}, we do the same thing, except that instead of creating a {@link javax.sql.DataSource} on the last line, we create a {@link org.apache.commons.dbcp.PoolingDriver}, and register the connectionPool with it. E.g.,:}

GenericObjectPool connectionPool = new GenericObjectPool(null);
DriverManagerConnectionFactory connectionFactory = new DriverConnectionFactory("jdbc:some:connect:string",null);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
PoolingDriver driver = new PoolingDriver();
driver.registerPool("example",connectionPool);

{@link org.apache.commons.dbcp.PoolingDriver} が生成される時にそれ自身に {@link java.sql.DriverManager} を登録するため、(登録の際に使用した "example" を使って)以下のような通常の方法で {@link java.sql.DriverManager} から {@link java.sql.Connection} を生成することができます: {@primary Since the {@link org.apache.commons.dbcp.PoolingDriver} registers itself with the {@link java.sql.DriverManager} when it is created, now you can just go to the {@link java.sql.DriverManager} to create your {@link java.sql.Connection}s, like you normally would:}

Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:example");

Q: なんだか複雑そうですが、簡単な方法はありませんか? {@primary Q: Sounds complicated, is there an easier way?}

A: {@link org.apache.commons.dbcp.PoolingDriver} を使用すれば必ずしもこの設定をコード内で行う必要はありません。 代わりにコネクションプールを定義する {@link org.apache.commons.jocl JOCL ドキュメント} を準備すれば実行時に {@link org.apache.commons.dbcp.PoolingDriver} が読み込みます。 {@primary A: If you're using the {@link org.apache.commons.dbcp.PoolingDriver}, you don't need to do this configuration in code. Instead, you can provide a {@link org.apache.commons.jocl JOCL document} that describes the connection pool, and let the {@link org.apache.commons.dbcp.PoolingDriver} discover it at runtime.}

{@link org.apache.commons.dbcp.PoolingDriver} が まだ登録されていないプールから {@link java.sql.Connection} を取得しようとした場合、 プールの設定内から指定された名前のリソースを探し、そのプールを生成します。 {@primary Specifically, if the {@link org.apache.commons.dbcp.PoolingDriver} is asked for a {@link java.sql.Connection} from a pool that has not yet been registered, it will look for a named resource from which to read the pool's configuration, and create that pool.}

"/eg" という名前のプールを JOCL ドキュメントにて作成する場合を例に挙げます。 このプールに接続するための文字列(URL)は "jdbc:apache:commons:dbcp:/eg" になります。 この設定を行うためにはプールのための JOCL の記述を行った resource を(クラスパス内のファイルとして)作成する必要があります。 この JOCL ドキュメントにはプールの取得元となる {@link org.apache.commons.dbcp.PoolableConnectionFactory} の設定を記述します。 例は以下のようになります: {@primary For example, suppose you create a pool named "/eg" from a JOCL document. The "connect string" for this pool will be "jdbc:apache:commons:dbcp:/eg". To do this, you'll need a create a resource (just a file in your classpath) containing a JOCL description of the pool. Specifically, this JOCL document should define a {@link org.apache.commons.dbcp.PoolableConnectionFactory} from which the pool will be obtained. For example:}

<object class="org.apache.commons.dbcp.PoolableConnectionFactory" xmlns="http://apache.org/xml/xmlns/jakarta/commons/jocl">
   <!-- (コンストラクタの)最初の引数となる ConnectionFactory -->
   <object class="org.apache.commons.dbcp.DriverManagerConnectionFactory">
      <string value="jdbc:some:connect:string"/>
      <object class="java.util.Properties" null="true"/>
   </object>
   <!-- (コンストラクタの)2番目の引数となる ObjectPool -->
   <object class="org.apache.commons.pool.impl.GenericObjectPool">
      <object class="org.apache.commons.pool.PoolableObjectFactory" null="true"/>
      <int value="10"/> <!-- アクティブなコネクションの最大数 -->
      <byte value="1"/> <!-- コネクションが使い尽くされている場合の処理, 0 = 失敗, 1 = 待機, 2 = 新たに生成 -->
      <long value="2000"/> <!-- 最長待機時間 -->
      <int value="10"/> <!-- アイドル状態のコネクションの最大数 -->
      <boolean value="false"/> <!-- コネクションを取得するときにテストするか -->
      <boolean value="false"/> <!-- コネクションを返すときにテストするか -->
      <long value="10000"/> <!-- プール内オブジェクト排除スレッドの実行間隔 -->
      <int value="5"/> <!-- 排除スレッドが一度のチェックで対象とするコネクションの数 -->
      <long value="5000"/> <!-- 排除対象となるまでの最短アイドル時間 -->
      <boolean value="true"/> <!-- アイドル状態のコネクションのテストを行うか -->
   </object>
   <!-- (コンストラクタの)3番目の引数となる KeyedObjectPoolFactory -->
   <object class="org.apache.commons.pool.StackKeyedObjectPoolFactory">
      <int value="5"/> <!-- アイドル状態のコネクションの最大数 -->
   </object>
   <string value="SELECT COUNT(*) FROM DUAL"/> <;!-- チェックに使用されるクエリー -->
   <boolean value="false"/> <!-- デフォルトで読み込み専用にするか -->
   <boolean value="true"/> <!-- デフォルトでオートコミットにするか -->
</object>
{@primary
<object class="org.apache.commons.dbcp.PoolableConnectionFactory" xmlns="http://apache.org/xml/xmlns/jakarta/commons/jocl">
   <!-- the first argument is the ConnectionFactory -->
   <object class="org.apache.commons.dbcp.DriverManagerConnectionFactory">
      <string value="jdbc:some:connect:string"/>
      <object class="java.util.Properties" null="true"/>
   </object>
   <!-- the next argument is the ObjectPool -->
   <object class="org.apache.commons.pool.impl.GenericObjectPool">
      <object class="org.apache.commons.pool.PoolableObjectFactory" null="true"/>
      <int value="10"/> <!-- max active -->
      <byte value="1"/> <!-- when exhausted action, 0 = fail, 1 = block, 2 = grow -->
      <long value="2000"/> <!-- max wait -->
      <int value="10"/> <!-- max idle -->
      <boolean value="false"/> <!-- test on borrow -->
      <boolean value="false"/> <!-- test on return -->
      <long value="10000"/> <!-- time between eviction runs -->
      <int value="5"/> <!-- number of connections to test per eviction run -->
      <long value="5000"/> <!-- min evictable idle time -->
      <boolean value="true"/> <!-- test while idle -->
   </object>
   <!-- the next argument is the KeyedObjectPoolFactory -->
   <object class="org.apache.commons.pool.StackKeyedObjectPoolFactory">
      <int value="5"/> <!-- max idle -->
   </object>
   <string value="SELECT COUNT(*) FROM DUAL"/> <;!-- validation query -->
   <boolean value="false"/> <!-- default read only -->
   <boolean value="true"/> <!-- default auto commit -->
</object>
}

このファイルを eg.jocl という名前でクラスパスの参照できる場所に配置すれば {@link org.apache.commons.dbcp.PoolingDriver} は自動的にこのファイルを検索します。 後は {@link org.apache.commons.dbcp.PoolingDriver} を(jdbc.drivers プロパティなどで)登録すれば {@link java.sql.DriverManager} を使った以下のような一般的な方法で {@link java.sql.Connection} を生成することができます: {@primary Simply save that file somewhere in your classpath as eg.jocl, and the {@link org.apache.commons.dbcp.PoolingDriver} will find it automatically. You need only register the {@link org.apache.commons.dbcp.PoolingDriver} (for example, using the jdbc.drivers property), and use the the {@link java.sql.DriverManager} to create your {@link java.sql.Connection}s, like you normally would:}

Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:/eg");

(スラッシュ("/")を付けなかった場合には定義ファイルをクラスパス内の org/apache/commons/dbcp/PoolingDriver/eg.jocl に配置しなくてはならなくなります。 詳細に関しては {@link java.lang.Class#getResource} を参照ください。) {@primary (Note that without the leading slash, the pool must be located at org/apache/commons/dbcp/PoolingDriver/eg.jocl within your classpath. See {@link java.lang.Class#getResource} for details.)}

@translator 日置 聡 @status firstdraft @update 2003/08/31