📄 jdbc 连接池.txt
字号:
JDBC连接池源码及示例源码
/*
功能:PoolManager.java连接池管理
Date:2002.4.28
Author:shiyq
. 加载和注册所有JDBC驱动程序;
. 根据一个特性文件中定义的特性,创建ConnectionPool对象;
. 将连接池名称映射到ConnectionPool对象上;
. 将客户请求传递到一个名称为Connection的特定对对象;
. 跟踪连接池中的客户,当最后一个客户完成工作时关闭连接.
*/
package erpb2b.connectionpool;
import java.sql.*;
import java.io.*;
import java.util.*;
//import LogWriter; 在同一目录下直接内部调用,故不需要声明
public class PoolManager {
static private PoolManager instance; //保存该类的单个实例的引用
static private int clients; //记忆有多少个客户使用连接池
private LogWriter logWriter;
private PrintWriter pw;
//实例变量drivers 和 pools 用于跟踪JDBC驱动程序和ConnectionPool实例
private Vector drivers = new Vector();
private Hashtable pools = new Hashtable();
//构造函数
//PoolManager空白容器
public PoolManager() {
init(); //初始化
}
//PoolManager的客户调用静态方法getInstance()获得该单个实例的引用
static synchronized public PoolManager getInstance() {
//如果没有,就创建一个实例
if (instance == null) {
instance = new PoolManager();
}
clients++; //客户连接数加1
return instance;
}
//初始化
private void init() {
// Log to System.err until we have read the logfile property
pw = new PrintWriter(System.err, true); //将System.err作为logWriter的缺省输出
logWriter = new LogWriter("PoolManager", LogWriter.INFO, pw);
//getResourceAsStream()方法是一个用于定位外部文件和为输入打开它的标准JDK方法
//getClass()方法获得一个Class的引用
//搜索的起点是放置类文件件的目录[CLASSPATH]
InputStream is = getClass().getResourceAsStream("/erpb2b.properties");
Properties dbProps = new Properties(); //创建一个Properties对象
try {
dbProps.load(is); //装入test.properties文件,并寻打logfile特性
} catch (Exception e) {
logWriter.log("Can't read the properties file. Make sure test.properties is in the CLASSPATH",
LogWriter.ERROR);
return;
}
String logFile = dbProps.getProperty("logfile","/erpb2b_log.txt"); //取logfile特性
if (logFile != null) { //如果指定了日志文件,就写入此文件
try {
pw = new PrintWriter(new FileWriter(logFile, true), true);
logWriter.setPrintWriter(pw);
}catch (IOException e){ //否则,写入System.ERR
logWriter.log("Can't open the log file: " + logFile +
". Using System.err instead", LogWriter.ERROR); }
} //end if
loadDrivers(dbProps); //调用loadDrivers()方法加载和注册由drivers特性指定的所有JDBC驱动程序
createPools(dbProps); //调用createPools()方法创建一个ConnectionPool
}
//loadDrivers()方法加载和注册JDBC驱动程序
private void loadDrivers(Properties props) {
String driverClasses = props.getProperty("drivers","com.sybase.jdbc2.jdbc.SybDriver");
StringTokenizer st = new StringTokenizer(driverClasses);
//使用StringTokenizer把drivers特性值分解为多个String 值,其中每个驱动程序类名对应一个String值,然后循环处理所有类名
while (st.hasMoreElements()){
String driverClassName = st.nextToken().trim();
try {
Driver driver = (Driver)Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
logWriter.log("Registered JDBC driver " + driverClassName,LogWriter.INFO);
}catch (Exception e) {
logWriter.log(e, "Can't register JDBC driver: " +
driverClassName, LogWriter.ERROR); }
} //end while
}
//createPools()方法创建ConnectionPool对象
private void createPools(Properties props) {
Enumeration propNames = props.propertyNames();
while (propNames.hasMoreElements()) {
String name = (String) propNames.nextElement();
if (name.endsWith(".url")) {
String poolName = name.substring(0, name.lastIndexOf("."));
String url = props.getProperty(poolName + ".url");
if (url == null) {
logWriter.log("No URL specified for " + poolName,
LogWriter.ERROR);
continue;
} //end if (url)
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxConns = props.getProperty(poolName +
".maxconns", "0");
int max;
try {
max = Integer.valueOf(maxConns).intValue();
}catch (NumberFormatException e) {
logWriter.log("Invalid maxconns value " + maxConns +
" for " + poolName, LogWriter.ERROR);
max = 0;
} //end try
String initConns = props.getProperty(poolName +
".initconns", "0");
int init;
try {
init = Integer.valueOf(initConns).intValue();
}catch (NumberFormatException e) {
logWriter.log("Invalid initconns value " + initConns +
" for " + poolName, LogWriter.ERROR);
init = 0;
} //end try
String loginTimeOut = props.getProperty(poolName +
".logintimeout", "5");
int timeOut;
try {
timeOut = Integer.valueOf(loginTimeOut).intValue();
} catch (NumberFormatException e) {
logWriter.log("Invalid logintimeout value " + loginTimeOut +
" for " + poolName, LogWriter.ERROR);
timeOut = 5;
} //end try
String logLevelProp = props.getProperty(poolName +
".loglevel", String.valueOf(LogWriter.ERROR));
int logLevel = LogWriter.INFO;
if (logLevelProp.equalsIgnoreCase("none")) {
logLevel = LogWriter.NONE;
} else
if (logLevelProp.equalsIgnoreCase("error")) {
logLevel = LogWriter.ERROR;
} else
if (logLevelProp.equalsIgnoreCase("debug")) {
logLevel = LogWriter.DEBUG;
}
ConnectionPool pool =
new ConnectionPool(poolName, url, user, password,
max, init, timeOut, pw, logLevel);
pools.put(poolName, pool);
}
}
}
//获得和返回连接
public Connection getConnection(String name) {
Connection conn = null;
ConnectionPool pool = (ConnectionPool) pools.get(name);
if (pool != null) {
try {
conn = pool.getConnection();
} catch (SQLException e) {
logWriter.log(e, "Exception getting connection from " +
name, LogWriter.ERROR);
} //end try
} //end if
return conn;
}
//返回连接
public void freeConnection(String name, Connection con) {
ConnectionPool pool = (ConnectionPool) pools.get(name);
if (pool != null) {
pool.freeConnection(con);
}
}
//关闭连接池
public synchronized void release() {
// Wait until called by the last client
if (--clients != 0) {
return;
}
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements()) {
ConnectionPool pool = (ConnectionPool) allPools.nextElement();
pool.release();
} //end while
Enumeration allDrivers = drivers.elements();
while (allDrivers.hasMoreElements()) {
Driver driver = (Driver) allDrivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
logWriter.log("Deregistered JDBC driver " +
driver.getClass().getName(), LogWriter.INFO);
} catch (SQLException e) {
logWriter.log(e, "Couldn't deregister JDBC driver: " +
driver.getClass().getName(), LogWriter.ERROR);
} //end try
} //end while(allDrivers)
} //end if
}
=================================================================================
以下是测试类
/*
连接池测试
*/
package erpb2b.connectionpool;
import java.sql.*;
/**
* This class tests the basic behavior of the connectiom pool
* implementation. To run the test you must have a db.properties
* file with a definition of a pool named "xbb2b", with maxconns
* set to 1. It's recommended that you do not specify a log file
* in db.properties and use loglevel debug for the "xbb2b" pool, so
* that you can see all pool messages intermixed with the messages
* printed by this class.
*
* @author Hans Bergsten, Gefion software (www.gefionsoftware.com)
*/
public class Test implements Runnable
{
static public void main(String[] args)
{
PoolManager poolManager = PoolManager.getInstance(); //创建一个PoolManager的实例
// Get a connection and return it
System.out.println("Get a connection and return it:");
Connection conn = poolManager.getConnection("erpb2b");
if (conn != null) {
System.out.println(" Got connection!");
poolManager.freeConnection("erpb2b", conn);
}
// Try to get a connection from a pool that doesn't exist
System.out.println("Try to get a connection from a pool that doesn't exist:");
conn = poolManager.getConnection("erpb2b");
if (conn == null){
System.out.println(" Didn't get connection!");
}
// Get a connection, close it, return it and try to get it
// again. The pool should throw away the closed connection
// and open a new one
System.out.println("Get a connection when the pooled one is bad:");
conn = poolManager.getConnection("erpb2b");
if (conn != null)
{
System.out.println(" Got connection! Close it and return it");
try {
conn.close();
} catch (SQLException e) {}
poolManager.freeConnection("erpb2b", conn);
}
conn = poolManager.getConnection("erpb2b");
if (conn != null) {
System.out.println(" Got connection!");
poolManager.freeConnection("erpb2b", conn);
}
// Try to get a connection from a pool that's empty.
// This requires the demo pool to be configured for
// max 1 connection. The second request should time-out
System.out.println("Try to get a connection from a pool that's empty:");
Connection conn1 = poolManager.getConnection("erpb2b");
if (conn1 != null){
System.out.println(" Got the first connection!");
}
Connection conn2 = poolManager.getConnection("erpb2b");
if (conn2 == null)
{
System.out.println(" Didn't get the second connection!");
}
poolManager.freeConnection("erpb2b", conn1);
// Wait for a connection until one is returned.
// This Thread gets the only connection and starts another
// Thread to also try to get one. Before the time-out,
// this Thread returns its connection
System.out.println("Wait for a connection until another thread returns one:");
conn1 = poolManager.getConnection("erpb2b");
if (conn1 != null)
{
System.out.println(" Got the first connection!");
Thread thread = new Thread(new Test());
thread.start();
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{ }
poolManager.freeConnection("erpb2b", conn1);
}
}
/**
* Runs a getConnection() in a separate Thread to test time-outs
*/
public void run()
{
PoolManager poolManager = PoolManager.getInstance();
Connection conn = poolManager.getConnection("erpb2b");
if (conn != null)
{
System.out.println(" Got the connection after waiting!");
poolManager.freeConnection("erpb2b", conn);
}
poolManager.release();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -