数据库连接池

数据库连接池,第1张

在实际应用开发中,特别是在WEB应用系统中,如果JSP、Servlet或EJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必须经历建立数据库连接、打开数据库、存取数据和关闭数据库连接等步骤,而连接并打开数据库是一件既消耗资源又费时的工作,如果频繁发生这种数据库 *** 作,系统的性能必然会急剧下降,甚至会导致系统崩溃。数据库连接池技术是解决这个问题最常用的方法,在许多应用程序服务器(例如:Weblogic,WebSphere,JBoss)中,基本都提供了这项技术,无需自己编程,但是,深入了解这项技术是非常必要的。

数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vector对象中,一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接,这样,通过复用这些已经建立的数据库连接,可以克服上述缺点,极大地节省系统资源和时间。

数据库连接池的主要 *** 作如下:

(1)建立数据库连接池对象(服务器启动)。

(2)按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。

(3)对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。

(4)存取数据库。

(5)关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。

(6)释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。

DataSource这个类必须运行在tomcat环境中才可以,而且要启动tomcat服务器,如果你单独的运行在jvm上是不可以的,你应该在jsp页面上调用这个类就可以了 ;不过你可以加个映射试试

或者自己写个连接池;用Java,这样在JSP中就可以调了;不用tomcat提供的连接池

我这有个你拿去改改就行了希望能满意

加的注释

package lmjadsofteffortsdb;

import javaio;

import javasql;

import javautil;

import javautilDate;

/

管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接

池的访问客户程序可以调用getInstance()方法访问本类的唯一实例

/

public class DBConnectionManager {

static private DBConnectionManager instance; // 唯一实例

static private int clients;

private Vector drivers = new Vector();

private PrintWriter log;

private Hashtable pools = new Hashtable();

/

返回唯一实例如果是第一次调用此方法,则创建实例

@return DBConnectionManager 唯一实例

/

public synchronized static DBConnectionManager getInstance() {

if (instance == null) {

instance = new DBConnectionManager();

}

//用看有多少实例被用

clients++;

return instance;

}

/

建构函数私有以防止其它对象创建本类实例

/

private DBConnectionManager() {

init();

}

/

return poolgetConnection();

将连接对象返回给由名字指定的连接池

@param name

在属性文件中定义的连接池名字

@param con

连接对象

/

public void freeConnection(String name, Connection con) {

DBConnectionPool pool = (DBConnectionPool) poolsget(name);

if (pool != null) {

poolfreeConnection(con);

}

}

/

获得一个可用的(空闲的)连接如果没有可用连接,且已有连接数小于最大连接数 限制,则创建并返回新连接

@param name

在属性文件中定义的连接池名字

@return Connection 可用连接或null

/

public Connection getConnection(String name) {

DBConnectionPool pool = (DBConnectionPool) poolsget(name);

if (pool != null) {

return poolgetConnection();

}

return null;

}

/

获得一个可用连接若没有可用连接,且已有连接数小于最大连接数限制, 则创建并返回新连接否则,在指定的时间内等待其它线程释放连接

@param name

连接池名字

@param time

以毫秒计的等待时间

@return Connection 可用连接或null

/

public Connection getConnection(String name, long time) {

DBConnectionPool pool = (DBConnectionPool) poolsget(name);

if (pool != null) {

return poolgetConnection(time);

}

return null;

}

/

关闭所有连接,撤销驱动程序的注册

/

public synchronized void release() {

// 等待直到最后一个客户程序调用

if (--clients != 0) {

return;

}

Enumeration allPools = poolselements();

while (allPoolshasMoreElements()) {

DBConnectionPool pool = (DBConnectionPool) allPoolsnextElement();

poolrelease();

}

Enumeration allDrivers = driverselements();

while (allDrivershasMoreElements()) {

Driver driver = (Driver) allDriversnextElement();

try {

DriverManagerderegisterDriver(driver);

log("撤销JDBC驱动程序 " + drivergetClass()getName() + "的注册");

} catch (SQLException e) {

log(e, "无法撤销下列JDBC驱动程序的注册: " + drivergetClass()getName());

}

}

}

/

根据指定属性创建连接池实例

@param props

连接池属性

/

private void createPools(Properties props) {

Enumeration propNames = propspropertyNames();

while (propNameshasMoreElements()) {

String name = (String) propNamesnextElement();

if (nameendsWith("url")) {

String poolName = namesubstring(0, namelastIndexOf(""));

String url = propsgetProperty(poolName + "url");

if (url == null) {

log("没有为连接池" + poolName + "指定URL");

continue;

}

String user = propsgetProperty(poolName + "user");

String password = propsgetProperty(poolName + "password");

String maxconn = propsgetProperty(poolName + "maxconn", "0");

int max;

try {

max = IntegervalueOf(maxconn)intValue();

} catch (NumberFormatException e) {

log("错误的最大连接数限制: " + maxconn + " 连接池: " + poolName);

max = 0;

}

DBConnectionPool pool = new DBConnectionPool(poolName, url,

user, password, max);

poolsput(poolName, pool);

log("成功创建连接池" + poolName);

}

}

}

/

读取属性完成初始化

/

private void init() {

InputStream is = getClass()getResourceAsStream("/dbproperties");

Properties dbProps = new Properties();

try {

dbPropsload(is);

} catch (Exception e) {

Systemerrprintln("不能读取属性文件 "

+ "请确保dbproperties在CLASSPATH指定的路径中");

return;

}

String logFile = dbPropsgetProperty("logfile",

"DBConnectionManagerlog");

try {

log = new PrintWriter(new FileWriter(logFile, true), true);

} catch (IOException e) {

Systemerrprintln("无法打开日志文件: " + logFile);

log = new PrintWriter(Systemerr);

}

loadDrivers(dbProps);

createPools(dbProps);

}

/

装载和注册所有JDBC驱动程序

@param props

属性

/

private void loadDrivers(Properties props) {

String driverClasses = propsgetProperty("drivers");

StringTokenizer st = new StringTokenizer(driverClasses);

while (sthasMoreElements()) {

String driverClassName = stnextToken()trim();

try {

Driver driver = (Driver) ClassforName(driverClassName)

newInstance();

DriverManagerregisterDriver(driver);

driversaddElement(driver);

log("成功注册JDBC驱动程序" + driverClassName);

} catch (Exception e) {

log("无法注册JDBC驱动程序: " + driverClassName + ", 错误: " + e);

}

}

}

/

将文本信息写入日志文件

/

private void log(String msg) {

logprintln(new Date() + ": " + msg);

}

/

将文本信息与异常写入日志文件

/

private void log(Throwable e, String msg) {

logprintln(new Date() + ": " + msg);

eprintStackTrace(log);

}

/

此内部类定义了一个连接池它能够根据要求创建新连接,直到预定的最 大连接数为止在返回连接给客户程序之前,它能够验证连接的有效性

/

class DBConnectionPool {

private int checkedOut;

private Vector freeConnections = new Vector();

private int maxConn;

private String name;

private String password;

private String URL;

private String user;

/

创建新的连接池

@param name

连接池名字

@param URL

数据库的JDBC URL

@param user

数据库帐号,或 null

@param password

密码,或 null

@param maxConn

此连接池允许建立的最大连接数

/

public DBConnectionPool(String name, String URL, String user,

String password, int maxConn) {

thisname = name;

thisURL = URL;

thisuser = user;

thispassword = password;

thismaxConn = maxConn;

}

/

将不再使用的连接返回给连接池

@param con

客户程序释放的连接

/

public synchronized void freeConnection(Connection con) {

// 将指定连接加入到向量末尾

freeConnectionsaddElement(con);

checkedOut--;

notifyAll();

}

/

从连接池获得一个可用连接如没有空闲的连接且当前连接数小于最大连接 数限制,则创建新连接如原来登记为可用的连接不再有效,则从向量删除之,

然后递归调用自己以尝试新的可用连接

/

public synchronized Connection getConnection() {

Connection con = null;

if (freeConnectionssize() > 0) {

// 获取向量中第一个可用连接

con = (Connection) freeConnectionsfirstElement();

freeConnectionsremoveElementAt(0);

try {

if (conisClosed()) {

log("从连接池" + name + "删除一个无效连接");

// 递归调用自己,尝试再次获取可用连接

con = getConnection();

}

} catch (SQLException e) {

log("从连接池" + name + "删除一个无效连接");

// 递归调用自己,尝试再次获取可用连接

con = getConnection();

}

} else if (maxConn == 0 || checkedOut < maxConn) {

con = newConnection();

}

if (con != null) {

checkedOut++;

}

return con;

}

/

从连接池获取可用连接可以指定客户程序能够等待的最长时间 参见前一个getConnection()方法

@param timeout

以毫秒计的等待时间限制

/

public synchronized Connection getConnection(long timeout) {

long startTime = new Date()getTime();

Connection con;

while ((con = getConnection()) == null) {

try {

wait(timeout);

} catch (InterruptedException e) {

}

if ((new Date()getTime() - startTime) >= timeout) {

// wait()返回的原因是超时

return null;

}

}

return con;

}

/

关闭所有连接

/

public synchronized void release() {

Enumeration allConnections = freeConnectionselements();

while (allConnectionshasMoreElements()) {

Connection con = (Connection) allConnectionsnextElement();

try {

conclose();

log("关闭连接池" + name + "中的一个连接");

} catch (SQLException e) {

log(e, "无法关闭连接池" + name + "中的连接");

}

}

freeConnectionsremoveAllElements();

}

/

创建新的连接 /

/

private Connection newConnection() {

Connection con = null;

try {

if (user == null) {

con = DriverManagergetConnection(URL);

}

} catch (Exception e) {

eprintStackTrace();

}

return con;

}

}

}

以上就是关于数据库连接池全部的内容,包括:数据库连接池、数据连接池在JSP页面正常使用,但是在java类中却出现异常、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9410428.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存