java写的一个连接池

 

package java.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;


/**
 * DBコネクション管理クラス
 *
 */
public class DBConnectionPool
{
	/** インスタンス */
	private static DBConnectionPool connectionPool  = null;

	/** コネクションを保持するベクトル */
	private Vector connections = null;

	/** 現在のコネクション数 */
	int currentCount = 0;


	/** 同時にデータベースに接続可能なコネクション数 */
	private static final int MAX_CONNECTION = Integer.parseInt(SystemProperties.get( "MAX_CONNECTION" ));

	/** 最小コネクション数 */
	private static final int MIN_CONNECTION = Integer.parseInt(SystemProperties.get( "MIN_CONNECTION" ));

	/** 最大待ち時間(秒)*/
	private static final int CONNECTION_TIMEOUT = Integer.parseInt(SystemProperties.get( "CONNECTION_TIMEOUT" ));

	/** コネクション取得待ち時間(ミリ秒) */
	private static final int WAIT_TIME = Integer.parseInt(SystemProperties.get( "WAIT_TIME" ));

	/** DBアクセスに必要な各値(環境に依存) */
	private static final String DRIVER = SystemProperties.get( "DRIVER_CLASS_NAME" );
	private static final String URL = SystemProperties.get( "URL" );
	private static final String USER = SystemProperties.get( "USER" );
	private static final String PASSWORD = SystemProperties.get( "PASSWORD" );


	/**
	 * DBConnectionPool インスタンスの取得
	 *
	 * @return インスタンスを戻します。
	 */
	public static DBConnectionPool getInstance() throws Exception
	{
		if( DBConnectionPool.connectionPool == null || !DBConnectionPool.checkConnectionValidity() )
		{
			DBConnectionPool.connectionPool = new DBConnectionPool();

		}

		return DBConnectionPool.connectionPool;

	}

	/**
	 * DBConnectionPool インスタンスの生成
	 * ※privateなので、外部からの生成(new)は不可能
	 */
	private DBConnectionPool() throws Exception
	{

		// DBアクセスに必要な各値を設定

		Class.forName( DRIVER );

		connections = new Vector();

		for( int i = 0; i < MIN_CONNECTION; i++ )
		{
			Connection connection = createConnection();
			connections.add( connection );
			currentCount++;

		}

	}

	/**
	 * コネクションの取得
	 * ※取得できない場合は引数で与えられた回数だけコネクション取得待ち時間おきにトライ
	 *
	 * @param count_ コネクション取得の試行回数。
	 * @return コネクション(取得できなかったた場合はnul)を戻します。
	 * @throws SQLException
	 */
	public synchronized Connection getConnection( int count_ ) throws SQLException
	{
		// 試行回数に達した場合は null を返す
		if( count_ < 1 )
		{
			return null;

		}

		// コネクションが残っていればプールから1つ取り出して提供する
		if( 0 < connections.size() )
		{
			Connection connection = ( Connection )connections.get( 0 );
			connections.remove( 0 );

			return connection;

		}
		else if( currentCount < MAX_CONNECTION )
		{
			currentCount++;
			return createConnection();

		}
		else
		{
			// コネクションが残っていなければXXミリ秒待機
			try
			{
				wait( WAIT_TIME );

			}
			catch( Exception e )
			{
				e.printStackTrace();

			}
			// 試行回数を1つ減らして再度取得を実行
			return getConnection( count_ - 1 );

		}

	}

	/**
	 * コネクションの返却
	 *
	 * @param connection_ 返却するコネクション。
	 */
	public synchronized void releaseConnection( Connection connection_ )
	{
		// プールに返されたコネクションを追加
		connections.add( connection_ );

	}

	/**
	 * コネクションの作成
	 *
	 * @return conn コネクション。
	 * @throws SQLException
	 */
	private Connection createConnection() throws SQLException
	{
		// 最大待ち時間を設定
		DriverManager.setLoginTimeout( CONNECTION_TIMEOUT );
		Connection conn = DriverManager.getConnection( URL, USER, PASSWORD );
		return conn;

	}

	/**
	 * コネクションの有効性チェック
	 *
	 * @return trueOrFalse 真偽。
	 */
	private static boolean checkConnectionValidity()
	{
		boolean trueOrFalse = true; //戻り値
		String validationQuery = "select 1"; //検証用クエリ

		Connection conn = null;
		Statement stmt = null;

		try
		{
			// プールされているコネクションで検証用クエリを実行
			if( 0 < connectionPool.connections.size() )
			{
				conn = ( Connection )connectionPool.connections.get( 0 );
				connectionPool.connections.remove( 0 );
				stmt = conn.createStatement();
				stmt.execute( validationQuery );

			}

		}
		catch( SQLException e )
		{
			// 接続エラーが発生した場合は戻り値をfalseとする
			if( e.getErrorCode() == 0 && "08S01".equals( e.getSQLState() ) )
			{
				trueOrFalse = false;

			}

		}
		finally
		{

			if( stmt != null )
			{
				try
				{
					stmt.close();

				}
				catch( SQLException e )
				{
				}
			}

			if( conn != null )
			{
				connectionPool.releaseConnection( conn );
			}

		}

		return trueOrFalse;

	}

	/**
	 * プールされているコネクションのクローズ
	 *
	 */
	public synchronized void closeConnections()
	{
		Connection connection = null;

		// プールからコネクションを取り出してクローズ
		while( 0 < connections.size() )
		{
			connection = ( Connection )connections.get( 0 );
			connections.remove( 0 );

			if( connection != null )
			{
				try
				{
					connection.close();
					connection = null;
				}
				catch( SQLException e )
				{
					// 特に何もしない
					System.out.println( "DBコネクションのクローズに失敗" );
				}
			}

		}

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值