当前位置:  技术问答>java相关

高分求数据库(SQL-Server 2000)连接池!!!!

    来源: 互联网  发布时间:2015-06-20

    本文导语:  高分求数据库连接池,最后有注释说明,详细一点;谢谢! | 一、数据库连接池类 DBConnectionPool,提供如下的方法:    1、从池中取得一个打开的连接;    2、将一个连接返回池中;  ...

高分求数据库连接池,最后有注释说明,详细一点;谢谢!

|
一、数据库连接池类 DBConnectionPool,提供如下的方法: 

  1、从池中取得一个打开的连接; 

  2、将一个连接返回池中; 

  3、在关闭时释放所有的资源,并关闭所有的连接。 

  另外,DBConnectionPool还处理连接失败,比如超时,通讯失败等错误,并且根据预定义的参数限制池中的连接数。 

二、管理者类,DBConnetionManager,是一个容器将连接池封装在内,并管理所有的连接池。它的方法有: 

  1、 调用和注册所有的jdbc驱动程序; 

  2、 根据参数表创建DBConnectionPool对象; 

  3、 映射连接池的名字和DBConnectionPool实例; 

  4、 当所有的连接客户退出后,关闭全部连接池。 

这些类的实现,以及如何在servlet中使用连接池的应用在随后的文章中讲解 
 


DBConnectionPool类代表一个由url标识的数据库连接池。前面,我们已经提到,jdbc的url由三个部分组成:协议标识(总是jdbc),子协议标识(例如,odbc.oracle),和数据库标识(跟特定的数据库有关)。连接池也具有一个名字,供客户程序引用。另外,连接池还有一个用户名,一个密码和一个最大允许连接数。如果web应用允许所有的用户使用某些数据库操作,而另一些操作是有限制的,则可以创建两个连接池,具有同样的url,不同的user name和password,分别处理两类不同的操作权限。现把DBConnectionPool详细介绍如下: 

  一、DBConnectionPool的构造 


  构造函数取得上述的所有参数: 

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

String password, int maxConn) { 

this.name = name; 

this.URL = URL; 

this.user = user; 

this.password = password; 

this.maxConn = maxConn; 



  将所有的参数保存在实例变量中。 


  二、从池中打开一个连接 


  DBConnectionPool提供两种方法来检查连接。两种方法都返回一个可用的连接,如果没有多余的连接,则创建一个新的连接。如果最大连接数已经达到,第一个方法返回null,第二个方法则等待一个连接被其他进程释放。 

public synchronized Connection getConnection() { 

Connection con = null; 

if (freeConnections.size() > 0) { 

// Pick the first Connection in the Vector 

// to get round-robin usage 

con = (Connection) freeConnections.firstElement(); 

freeConnections.removeElementAt(0); 

try { 

if (con.isClosed()) { 

log("Removed bad connection from " + name); 

// Try again recursively 

con = getConnection(); 





catch (SQLException e) { 

log("Removed bad connection from " + name); 

// Try again recursively 

con = getConnection(); 





else if (maxConn == 0 || checkedOut = timeout) { 

// Timeout has expired 

return null; 





return con; 




  局部变量startTime初始化当前的时间。一个while循环首先尝试获得一个连接,如果失败,wait()函数被调用来等待需要的时间。后面会看到,Wait()函数会在另一个进程调用notify()或者notifyAll()时返回,或者等到时间流逝完毕。为了确定wait()是因为何种原因返回,我们用开始时间减去当前时间,检查是否大于timeout。如果结果大于timeout,返回null,否则,在此调用getConnection()函数。 

|
四、将一个连接返回池中 


  DBConnectionPool类中有一个freeConnection方法以返回的连接作为参数,将连接返回连接池。 


public synchronized void freeConnection(Connection con) { 

// Put the connection at the end of the Vector 

freeConnections.addElement(con); 

checkedOut--; 

notifyAll(); 



  连接被加在freeConnections向量的最后,占用的连接数减1,调用notifyAll()函数通知其他等待的客户现在有了一个连接。 

五、关闭 


  大多数servlet引擎提供完整的关闭方法。数据库连接池需要得到通知以正确地关闭所有的连接。DBConnectionManager负责协调关闭事件,但连接由各个连接池自己负责关闭。方法relase()由DBConnectionManager调用。 
public synchronized void release() { 

Enumeration allConnections = freeConnections.elements(); 

while (allConnections.hasMoreElements()) { 

Connection con = (Connection) allConnections.nextElement(); 

try { 

con.close(); 

log("Closed connection for pool " + name); 



catch (SQLException e) { 

log(e, "Can not close connection for pool " + name); 





freeConnections.removeAllElements(); 



本方法遍历freeConnections向量以关闭所有的连接。 












DBConnetionManager的构造函数是私有函数,以避免其他类创建其实例。 

private DBConnectionManager() { 

init(); 



  DBConnetionManager的客户调用getInstance()方法来得到该类的单一实例的引用。 

static synchronized public DBConnectionManager getInstance() { 

if (instance == null) { 

instance = new DBConnectionManager(); 



clients++; 

return instance; 



  单一的实例在第一次调用时创建,以后的调用返回该实例的静态应用。一个计数器纪录所有的客户数,直到客户释放引用。这个计数器在以后用来协调关闭连接池。 


  一、初始化 

  构造函数调用一个私有的init()函数初始化对象。 

private void init() { 

InputStream is = getClass().getResourceAsStream("/db.properties"); 

Properties dbProps = new Properties(); 

try { 

dbProps.load(is); 



catch (Exception e) { 

System.err.println("Can not read the properties file. " + 

"Make sure db.properties is in the CLASSPATH"); 

return; 



String logFile = dbProps.getProperty("logfile", 

"DBConnectionManager.log"); 

try { 

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



catch (IOException e) { 

System.err.println("Can not open the log file: " + logFile); 

log = new PrintWriter(System.err); 



loadDrivers(dbProps); 

createPools(dbProps); 



  方法getResourceAsStream()是一个标准方法,用来打开一个外部输入文件。文件的位置取决于类加载器,而标准的类加载器从classpath开始搜索。Db.properties文件是一个Porperties格式的文件,保存在连接池中定义的key-value对。下面一些常用的属性可以定义: 

   drivers 以空格分开的jdbc驱动程序的列表 

   logfile 日志文件的绝对路径 

  每个连接池中还使用另一些属性。这些属性以连接池的名字开头: 

   .url数据库的JDBC URL 

   .maxconn最大连接数。0表示无限。 

   .user连接池的用户名 

   .password相关的密码 

  url属性是必须的,其他属性可选。用户名和密码必须和所定义的数据库匹配。 

  下面是windows平台下的一个db.properties文件的例子。有一个InstantDB连接池和一个通过odbc连接的access数据库的数据源,名字叫demo。 

drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver 

logfile=D:\user\src\java\DBConnectionManager\log.txt 

idb.url=jdbc:idb:c:\local\javawebserver1.1\db\db.prp 

idb.maxconn=2 

access.url=jdbc:odbc:demo 

access.user=demo 

access.password=demopw 

注意,反斜线在windows平台下必须双写。

|
初始化方法init()创建一个Porperties对象并装载db.properties文件,然后读取日志文件属性。如果日志文件没有命名,则使用缺省的名字DBConnectionManager.log在当前目录下创建。在此情况下,一个系统错误被纪录。 

方法loadDrivers()将指定的所有jdbc驱动程序注册,装载。 

private void loadDrivers(Properties props) { 

String driverClasses = props.getProperty("drivers"); 

StringTokenizer st = new StringTokenizer(driverClasses); 

while (st.hasMoreElements()) { 

String driverClassName = st.nextToken().trim(); 

try { 

Driver driver = (Driver) 

Class.forName(driverClassName).newInstance(); 

DriverManager.registerDriver(driver); 

drivers.addElement(driver); 

log("Registered JDBC driver " + driverClassName); 



catch (Exception e) { 

log("Can not register JDBC driver: " + 

driverClassName + ", Exception: " + e); 







  loadDrivers()使用StringTokenizer将dirvers属性分成单独的driver串,并将每个驱动程序装入java虚拟机。驱动程序的实例在JDBC 的DriverManager中注册,并加入一个私有的向量drivers中。向量drivers用来关闭和注销所有的驱动程序。 

  然后,DBConnectionPool对象由私有方法createPools()创建。 

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) { 

log("No URL specified for " + poolName); 

continue; 



String user = props.getProperty(poolName + ".user"); 

String password = props.getProperty(poolName + ".password"); 

String maxconn = props.getProperty(poolName + ".maxconn", "0"); 

int max; 

try { 

max = Integer.valueOf(maxconn).intValue(); 



catch (NumberFormatException e) { 

log("Invalid maxconn value " + maxconn + " for " + 

poolName); 

max = 0; 



DBConnectionPool pool = 

new DBConnectionPool(poolName, url, user, password, max); 

pools.put(poolName, pool); 

log("Initialized pool " + poolName); 







  一个枚举对象保存所有的属性名,如果属性名带有.url结尾,则表示是一个连接池对象需要被实例化。创建的连接池对象保存在一个Hashtable实例变量中。连接池名字作为索引,连接池对象作为值  
 

 现在我们结合DBConnetionManager和DBConnectionPool类来讲解servlet中连接池的使用: 

  一、首先简单介绍一下Servlet的生命周期: 

  Servlet API定义的servlet生命周期如下: 

1、 Servlet 被创建然后初始化(init()方法)。 

2、 为0个或多个客户调用提供服务(service()方法)。 

3、 Servlet被销毁,内存被回收(destroy()方法)。 

  二、servlet中使用连接池的实例 

  使用连接池的servlet有三个阶段的典型表现是: 

1. 在init()中,调用DBConnectionManager.getInstance()然后将返回的引用保存在实例变量中。 


2. 在sevice()中,调用getConnection(),执行一系列数据库操作,然后调用freeConnection()归还连接。 

3. 在destroy()中,调用release()来释放所有的资源,并关闭所有的连接。 

  下面的例子演示如何使用连接池。 

import java.io.*; 

import java.sql.*; 

import javax.servlet.*; 

import javax.servlet.http.*; 

public class TestServlet extends HttpServlet { 

private DBConnectionManager connMgr; 



public void init(ServletConfig conf) throws ServletException { 

super.init(conf); 

connMgr = DBConnectionManager.getInstance(); 




public void service(HttpServletRequest req, HttpServletResponse res) 

throws IOException { 

res.setContentType("text/html"); 

PrintWriter out = res.getWriter(); 

Connection con = connMgr.getConnection("idb"); 

if (con == null) { 

out.println("Cant get connection"); 

return; 



ResultSet rs = null; 

ResultSetMetaData md = null; 

Statement stmt = null; 

try { 

stmt = con.createStatement(); 

rs = stmt.executeQuery("SELECT * FROM EMPLOYEE"); 

md = rs.getMetaData(); 

out.println(" 
Employee data 
"); 

while (rs.next()) { 

out.println(" 
"); 

for (int i = 1; i 

    
 
 

您可能感兴趣的文章:

  • 高分求教,linux下的GPRS连接!!!
  • 那位大哥给我发份连接sql2000的jdbc驱动,高分!
  • 高分求助:如何监测iptables配置的透明网关的内部网连接状态?
  • 高分求助在线等...连接池的问题
  • 有关数据库连接两种方式的比较??(高分求解)
  • 请问如何将com.inet.tds.TdsDriver的限制去掉?它好像只能接受3个连接。高分相送!
  • 高分请教:我用linux作网关,但我在内网不能连接外网的vpn(具体情况见帖),请问如何解决!谢谢
  • JDBC效率问题,才2,3张表连接查询就慢得受不了?高分求解......
  • 高分求购:对数据库(oracel)的连接、添加、编辑、等操作的javaBean源程序
  • 高分求解两台都在防火墙NAT后面的主机是如何通过UPnP建立起BT连接的,说明具体过程?
  • ★高分请教一个简单问题,关于JSP连接SQLServer2000★
  • 高手请教?高分!在Linux下怎样设置局域网连接?
  • [高分]我在wmWare上安装了Redhat Linux4,怎样才能和主机通过网络连接?
  • [高分求救]Jbuilder7连接不上sqlserver,为什么,大家帮帮忙!
  • 如何在JSP程序中连接MySql?(高分等待)
  • resin支持连接池吗?为什么我的连接池报错??高分悬赏!!
  • [100分]高分求教,如何能够单步控制TCP的连接?
  • 高分求教!!!JSP连接Oracle小程序。
  • 高分求解:我这样的配置如何使用连接池?
  • 高分请教数据库连接池的实现方法,在线给分!!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 高分求助高分求助高分求助高分求助高分求助高分求助
  • 谁参加过weblogic的证书考试,是否有经验可供参考?高分高分高高分
  • 哪里有JB6下载啊,高分相送,救命
  • 高分求救!我在uclinux上运行应用程序时出现内存分配错误,不知如何解决,解决者高分!!
  • 哪里去找中文的EJB文章?高分悬赏!
  • 有jsp的upload和download 代码么,高分相报!
  • (高分求助)请问,那里有软件开发的<设计文档>
  • 高分寻求jsp代码(网上调查系统,新闻发布系统)就这点分了
  • 高分求购做饼图、线形图的源吗?
  • 关于linu下的中文输入.(高分:300)
  • 一个简单的问题,高分求助!!!
  • 高分求购jbulider6得注册码,企业版本,个人版本都要
  • Linux远程访问的问题,高分求教:)
  • 高分请教:我用linux作网关,但我在内网不能连接外网的vpn(具体情况见帖),请问如何解决!谢谢 iis7站长之家
  • 高分求“Ration Rose”&"JBuilder6.0"&"VisualCafe"
  • VJ的一个问题,高分求助,熟悉VJ得请进!
  • 高分求购:linux和unix命令大全电子文档
  • 急救:关于BLOB数据类型---在线等待,高分相送!
  • 求UNIXWARE7.11的原版下载,高分相赠,在线等待!!!
  • 关于java?高分相送!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3