トッカンソフトウェア

DBCP2でコネクションプール


今回はDBCP2を使って、コネクションプールからDBコネクションを取得してみます。
単純はJDBCの処理は PostgreSQLをWindowsで使う を参照して下さい。

ライブラリの取得

DBCP2を使うにはDBCP、Logging、PoolのJarが必要になります。それぞれApacheの公式ページからダウンロードします。

Commons DBCP Apacheはこちら (https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi)


Commons DBCP Loggingはこちら (https://commons.apache.org/proper/commons-logging/download_logging.cgi)


Commons DBCP Poolはこちら (https://commons.apache.org/proper/commons-pool/download_pool.cgi)


それぞれプロジェクトフォルダに入れます。


Mavenでライブラリを取得する場合、DBCPだけで良いです。
				
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>javaTest4</groupId>
	<artifactId>javaTest4</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<build>
		<sourceDirectory>src</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.1.1</version>
		</dependency>
	</dependencies>
</project>

			

単純なサンプル

PropertiesクラスのオブジェクトにDB接続情報をセットし、BasicDataSourceFactory.createDataSourceでデータ・ソースを作成します。
データ・ソースよりコネクションを取得でき、後は通常と同じように使用できます。
※使い終わったら必ず、closeメソッドを呼び出してください。
				

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSourceFactory;

public class Posgre1 {
	public static void main(String[] args) {
		try {
			connectionTest();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * コネクションの取得
	 * 
	 * @throws Exception 実行時例外
	 */
	public static void connectionTest() throws Exception {
		Connection conn = null;

		try {

			// DB接続情報の指定
			Properties props = new Properties();
			props.setProperty("username", "postgres");
			props.setProperty("password", "ps");
			props.setProperty("url", "jdbc:postgresql://localhost:5432/postgres");
			props.setProperty("driverClassName", "org.postgresql.Driver");

			// コネクションの取得
			DataSource ds = BasicDataSourceFactory.createDataSource(props);
			conn = ds.getConnection();

			// SELECTのテスト
			selectTest(conn);

		} catch (Exception e) {
			throw e;
		} finally {
			if (conn != null) {
				conn.close();
			}
		}
	}

	/**
	 * データ取得
	 * 
	 * @param conn コネクション
	 * @throws SQLException SQL例外
	 */
	public static void selectTest(Connection conn) throws SQLException {

		try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select id from m_user");) {

			// 結果の表示
			while (rs.next()) {
				System.out.println(rs.getString("id"));
			}
		}
	}
}


			
プロパティ指定 内容
username DBにログインするユーザ
password パスワード
url JDBCの接続文字
driverClassName DBに接続するドライバ

その他の指定は、公式ページ(https://commons.apache.org/proper/commons-dbcp/configuration.html)を参照ください。


DB接続切れ対策

しばらくアクセスしない場合、コネクションプールで保持しているコネクションが切れることがあります。
コネクション取得時や、指定時間が経過したときなどにコネクションが切断されているか調べ、切断されている場合はコネクションプールから破棄できます。

基本処理は単純な処理と同様なので省略。Propertiesクラスのオブジェクトに指定情報をセットする処理に以下を追加します。
				
			//接続チェック用SQL(PostgreSQL)
			props.setProperty("validationQuery", "SELECT 1");
			
			//接続チェック用SQL(Oracle)
			//props.setProperty("validationQuery", "SELECT 1 FROM DUAL");
			
			//コネクション取得時に接続チェック
			props.setProperty("testOnBorrow", "true");
			
			//アイドル時間が指定時間経過した場合、接続チェック
			props.setProperty("testWhileIdle", "true");
			
			//指定時間経過でコネクションチェック(ミリ秒指定)
			props.setProperty("timeBetweenEvictionRunsMillis", "" + (1000 * 60 * 30));

			//指定時間経過でコネクション破棄(ミリ秒指定)
			//props.setProperty("minEvictableIdleTimeMillis", "" + (1000 * 60 * 30));

			
プロパティ指定 内容
validationQuery 接続チェック用SQL
testOnBorrow コネクション取得時に接続チェック
testWhileIdle アイドル時間が指定時間経過した場合、接続チェック
timeBetweenEvictionRunsMillis 指定時間経過でコネクションチェック(ミリ秒指定)
minEvictableIdleTimeMillis 指定時間経過でコネクション破棄(ミリ秒指定)

コネクション数

				
			// 初期コネクション数
			props.setProperty("initialSize", "0");

			// 最大コネクション数
			props.setProperty("maxTotal", "8");

			// アイドル状態で残しておく最大コネクション数
			props.setProperty("maxIdle", "8");

			// アイドル状態で最低限、保持しておくコネクション数
			props.setProperty("minIdle", "0");

			
プロパティ指定 内容
initialSize 初期コネクション数
maxTotal 最大コネクション数
maxIdle アイドル状態で残しておく最大コネクション数
minIdle アイドル状態で最低限、保持しておくコネクション数

コネクションプールの取得状態

コネクションプールから、どれだけコネクションを取得している、取得できるかを調べることができます。
				

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;

public class Posgre1 {
	public static void main(String[] args) {
		try {
			connectionTest();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * コネクションの取得
	 * 
	 * @throws Exception 実行時例外
	 */
	public static void connectionTest() throws Exception {
		Connection conn = null;

		try {

			// DB接続情報の指定
			Properties props = new Properties();
			props.setProperty("username", "postgres");
			props.setProperty("password", "ps");
			props.setProperty("url", "jdbc:postgresql://localhost:5432/postgres");
			props.setProperty("driverClassName", "org.postgresql.Driver");

			// コネクションの取得
			DataSource ds = BasicDataSourceFactory.createDataSource(props);
			conn = ds.getConnection();

			BasicDataSource bds = (BasicDataSource) ds;
			// コネクションプールから取得しているコネクション数を取得
			System.out.println(bds.getNumActive());
			// コネクションプールの余っているコネクション数を取得
			System.out.println(bds.getNumIdle());
			// コネクションプールから最大取得できるコネクション数を取得
			System.out.println(bds.getMaxTotal());

			// SELECTのテスト
			selectTest(conn);

		} catch (Exception e) {
			throw e;
		} finally {
			if (conn != null) {
				conn.close();
			}
		}
	}

	/**
	 * データ取得
	 * 
	 * @param conn コネクション
	 * @throws SQLException SQL例外
	 */
	public static void selectTest(Connection conn) throws SQLException {

		try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select id from m_user");) {

			// 結果の表示
			while (rs.next()) {
				System.out.println(rs.getString("id"));
			}
		}
	}
}

			

ページのトップへ戻る