java 数据库连接池代码_(转)经典的java数据库连接池代码

package web.db;

import java.sql.Connection;

import java.sql.DatabaseMetaData;

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.Enumeration;

import java.util.Vector;

public class ConnectionPool

{

private String jdbcDriver = ""; // 数据库驱动

private String dbUrl = ""; // 数据 URL

private String dbUsername = ""; // 数据库用户名

private String dbPassword = ""; // 数据库用户密码

private String testTable = ""; //

测试连接是否可用的测试表名,默认没有测试表

private int initialConnections = 10; //

连接池的初始大小

private int incrementalConnections = 5;//

连接池自动增加的大小

private int maxConnections = 50; //

连接池最大的大小

private Vector connections = null; //

存放连接池中数据库连接的向量 , 初始时为 null

// 它中存放的对象为 PooledConnection 型

public ConnectionPool()

{

}

public ConnectionPool(String jdbcDriver,

String dbUrl, String dbUsername, String dbPassword)

{

this.jdbcDriver =

jdbcDriver;

this.dbUrl = dbUrl;

this.dbUsername =

dbUsername;

this.dbPassword =

dbPassword;

}

public synchronized void createPool() throws

Exception

{

// 确保连接池没有创建

// 如果连接池己经创建了,保存连接的向量

connections 不会为空

if (connections !=

null)

{

return; //

如果己经创建,则返回

}

// 实例化 JDBC Driver

中指定的驱动类实例

Driver driver = (Driver)

(Class.forName(this.jdbcDriver).newInstance());

DriverManager.registerDriver(driver);

// 注册 JDBC 驱动程序

// 创建保存连接的向量 , 初始时有 0

个元素

connections = new

Vector();

// 根据 initialConnections

中设置的值,创建连接。

createConnections(this.initialConnections);

System.out.println("

数据库连接池创建成功! ");

}

@SuppressWarnings("unchecked")

private void createConnections(int

numConnections) throws SQLException

{

// 循环创建指定数目的数据库连接

for (int x = 0; x

< numConnections; x++)

{

//

是否连接池中的数据库连接的数量己经达到最大?最大值由类成员 maxConnections

// 指出,如果

maxConnections 为 0 或负数,表示连接数量没有限制。

//

如果连接数己经达到最大,即退出。

if

(this.maxConnections > 0

&& this.connections.size()

>= this.maxConnections)

{

break;

}

// add a

new PooledConnection object to connections vector

//

增加一个连接到连接池中(向量 connections 中)

try

{

connections.addElement(new

PooledConnection(newConnection()));

}

catch

(SQLException e)

{

System.out.println("

创建数据库连接失败! " + e.getMessage());

throw

new SQLException();

}

System.out.println("

数据库连接己创建 ......");

}

}

private Connection newConnection() throws

SQLException

{

// 创建一个数据库连接

Connection conn =

DriverManager.getConnection(dbUrl, dbUsername, dbPassword);

//

如果这是第一次创建数据库连接,即检查数据库,获得此数据库允许支持的

// 最大客户连接数目

// connections.size()==0

表示目前没有连接己被创建

if (connections.size() ==

0)

{

DatabaseMetaData

metaData = conn.getMetaData();

int

driverMaxConnections = metaData.getMaxConnections();

// 数据库返回的

driverMaxConnections 若为 0 ,表示此数据库没有最大

//

连接限制,或数据库的最大连接限制不知道

//

driverMaxConnections 为返回的一个整数,表示此数据库允许客户连接的数目

//

如果连接池中设置的最大连接数量大于数据库允许的连接数目 , 则置连接池的最大

//

连接数目为数据库允许的最大数目

if

(driverMaxConnections > 0

&& this.maxConnections

> driverMaxConnections)

{

this.maxConnections

= driverMaxConnections;

}

}

return conn; //

返回创建的新的数据库连接

}

public synchronized Connection getConnection()

throws SQLException

{

// 确保连接池己被创建

if (connections ==

null)

{

return

null; // 连接池还没创建,则返回 null

}

Connection conn =

getFreeConnection(); // 获得一个可用的数据库连接

//

如果目前没有可以使用的连接,即所有的连接都在使用中

while (conn == null)

{

//

等一会再试

wait(250);

conn =

getFreeConnection(); // 重新再试,直到获得可用的连接,如果

//

getFreeConnection() 返回的为 null

//

则表明创建一批连接后也不可获得可用连接

}

return conn;//

返回获得的可用的连接

}

private Connection getFreeConnection() throws

SQLException

{

// 从连接池中获得一个可用的数据库连接

Connection conn =

findFreeConnection();

if (conn == null)

{

//

如果目前连接池中没有可用的连接

//

创建一些连接

createConnections(incrementalConnections);

//

重新从池中查找是否有可用连接

conn =

findFreeConnection();

if (conn

== null)

{

//

如果创建连接后仍获得不到可用的连接,则返回 null

return

null;

}

}

return conn;

}

private Connection findFreeConnection() throws

SQLException

{

Connection conn = null;

PooledConnection pConn =

null;

// 获得连接池向量中所有的对象

Enumeration enumerate =

connections.elements();

// 遍历所有的对象,看是否有可用的连接

while

(enumerate.hasMoreElements())

{

pConn =

(PooledConnection) enumerate.nextElement();

if

(!pConn.isBusy())

{

//

如果此对象不忙,则获得它的数据库连接并把它设为忙

conn

= pConn.getConnection();

pConn.setBusy(true);

//

测试此连接是否可用

if

(!testConnection(conn))

{

//

如果此连接不可再用了,则创建一个新的连接,

//

并替换此不可用的连接对象,如果创建失败,返回 null

try

{

conn

= newConnection();

}

catch

(SQLException e)

{

System.out.println("

创建数据库连接失败! " + e.getMessage());

return

null;

}

pConn.setConnection(conn);

}

break;

// 己经找到一个可用的连接,退出

}

}

return conn;//

返回找到到的可用连接

}

private boolean testConnection(Connection

conn)

{

try

{

//

判断测试表是否存在

if

(testTable.equals(""))

{

//

如果测试表为空,试着使用此连接的 setAutoCommit() 方法

//

来判断连接否可用(此方法只在部分数据库可用,如果不可用 ,

//

抛出异常)。注意:使用测试表的方法更可靠

conn.setAutoCommit(true);

}

else

{//

有测试表的时候使用测试表测试

//

check if this connection is valid

Statement

stmt = conn.createStatement();

ResultSet

rs = stmt.executeQuery("select count(*) from " + testTable);

rs.next();

System.out.println(testTable

+ ":表的记录数为:" + rs.getInt(1));

}

}

catch (SQLException e)

{

//

上面抛出异常,此连接己不可用,关闭它,并返回 false;

e.printStackTrace();

closeConnection(conn);

return

false;

}

// 连接可用,返回 true

return true;

}

public void returnConnection(Connection

conn)

{

//

确保连接池存在,如果连接没有创建(不存在),直接返回

if (connections ==

null)

{

System.out.println("

连接池不存在,无法返回此连接到连接池中 !");

return;

}

PooledConnection pConn =

null;

Enumeration enumerate =

connections.elements();

//

遍历连接池中的所有连接,找到这个要返回的连接对象

while

(enumerate.hasMoreElements())

{

pConn =

(PooledConnection) enumerate.nextElement();

//

先找到连接池中的要返回的连接对象

if (conn

== pConn.getConnection())

{

//

找到了 , 设置此连接为空闲状态

pConn.setBusy(false);

break;

}

}

}

public synchronized void refreshConnections()

throws SQLException

{

// 确保连接池己创新存在

if (connections ==

null)

{

System.out.println("

连接池不存在,无法刷新 !");

return;

}

PooledConnection pConn =

null;

Enumeration enumerate =

connections.elements();

while

(enumerate.hasMoreElements())

{

//

获得一个连接对象

pConn =

(PooledConnection) enumerate.nextElement();

// 如果对象忙则等

5 秒 ,5 秒后直接刷新

if

(pConn.isBusy())

{

wait(5000);

// 等 5 秒

}

//

关闭此连接,用一个新的连接代替它。

closeConnection(pConn.getConnection());

pConn.setConnection(newConnection());

pConn.setBusy(false);

}

}

public synchronized void closeConnectionPool()

throws SQLException

{

// 确保连接池存在,如果不存在,返回

if (connections ==

null)

{

System.out.println("

连接池不存在,无法关闭 !");

return;

}

PooledConnection pConn =

null;

Enumeration enumerate =

connections.elements();

while

(enumerate.hasMoreElements())

{

pConn =

(PooledConnection) enumerate.nextElement();

// 如果忙,等 5

if

(pConn.isBusy())

{

wait(5000);

// 等 5 秒

}

// 5

秒后直接关闭它

closeConnection(pConn.getConnection());

//

从连接池向量中删除它

connections.removeElement(pConn);

}

// 置连接池为空

connections = null;

}

private void closeConnection(Connection

conn)

{

try

{

conn.close();

}

catch (SQLException e)

{

System.out.println("

关闭数据库连接出错: " + e.getMessage());

}

}

private void wait(int mSeconds)

{

try

{

Thread.sleep(mSeconds);

}

catch (InterruptedException

e)

{

}

}

public int getInitialConnections()

{

return

this.initialConnections;

}

public void setInitialConnections(int

initialConnections)

{

this.initialConnections =

initialConnections;

}

public int getIncrementalConnections()

{

return

this.incrementalConnections;

}

public void setIncrementalConnections(int

incrementalConnections)

{

this.incrementalConnections

= incrementalConnections;

}

public int getMaxConnections()

{

return

this.maxConnections;

}

public void setMaxConnections(int

maxConnections)

{

this.maxConnections =

maxConnections;

}

public String getTestTable()

{

return this.testTable;

}

public void setTestTable(String

testTable)

{

this.testTable =

testTable;

}

class PooledConnection

{

Connection connection =

null;// 数据库连接

boolean busy = false; //

此连接是否正在使用的标志,默认没有正在使用

// 构造函数,根据一个 Connection 构告一个

PooledConnection 对象

public

PooledConnection(Connection connection)

{

this.connection

= connection;

}

// 返回此对象中的连接

public Connection

getConnection()

{

return

connection;

}

// 设置此对象的,连接

public void

setConnection(Connection connection)

{

this.connection

= connection;

}

// 获得对象连接是否忙

public boolean

isBusy()

{

return

busy;

}

// 设置对象的连接正在忙

public void setBusy(boolean

busy)

{

this.busy

= busy;

}

}

}

测试类:

代码如下:

package web.db;

import

java.sql.Connection;

public class ConnectionPoolTest

{ public

static void main(String[] args) throws Exception

{ ConnectionPool connPool = new

ConnectionPool("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@127.0.0.1:1521:ORCL", "scott",

"tiger"); connPool.createPool(); Connection conn =

connPool.getConnection(); connPool.closeConnectionPool(); connPool.setTestTable("EMP"); } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值