登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - JAVA 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

数据库连接池java实现小结
发表日期:2003-05-28作者:copyright(原作)[] 出处:  

<br><P>       因为工作需要要使用到连接池,所以拜读了互联网上众多前辈的文章,学了不少经验,这里想做一个小结,加上自己的想法和在一起,希望能给大家一些帮助。</P>

<H3>目的:</H3>

<UL>

<LI>消除数据库频繁连接带来的开销和瓶颈。</LI></UL>

<H3>解决方案:</H3>

<UL>

<LI>不过多的限制用户的使用,既不能太多的要求用户按规定的方法得到和使用数据库连</LI></UL>

<UL>

<LI>尽量保持用户的习惯</LI></UL>

<P>目前的很多方法都是要求用户只能按规定方法使用连接,不能使用直接关闭数据连接的方法。解决办法就是使用代理类,来中间解决。可以参考<A href="http://www-900.ibm.com/developerWorks/cn/java/l-connpoolproxy/index.shtml">http://www-900.ibm.com/developerWorks/cn/java/l-connpoolproxy/index.shtml</A></P>

<UL>

<LI>能维护连接的正常状态</LI></UL>

<P>因为针对数据库连接创建的资源,如果不能及时的释放,就会影响下一次数据连接的使用。例如在sql 2k中,一个连接不同创建多条Statement否则操作时会有数据连接占线的异常,所以必须在归还连接以后释放这些资源。</P>

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE>

   <A href="file://判">//判</A>断是使用了createStatement语句<BR>   if (CREATESTATE.equals(method.getName()))<BR>   {<BR>    obj = method.invoke(conn, args);<BR>    statRef = (Statement)obj;//记录语句<BR>    return obj;<BR>   }

</CODE></PRE></TD></TR></TBODY></TABLE></P>

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE>   <A href="file://判">//判</A>断是否调用了close的方法,如果调用close方法则把连接置为无用状态<BR>   if(CLOSE.equals(method.getName()))<BR>   {<BR>    <A href="file://设">//设</A>置不使用标志<BR>    setIsFree(false);<BR>    <A href="file://检">//检</A>查是否有后续工作,清除该连接无用资源<BR>    if (statRef != null)<BR>     statRef.close();<BR>    if (prestatRef != null)<BR>     prestatRef.close();<BR>    return null;<BR>   }<BR></CODE></PRE></TD></TR></TBODY></TABLE></P>

<UL>

<LI>正确保护类不被违例使用</LI></UL>

<P>一个考虑就是不能让用户随便使用代理类,而只能自己使用,一个就是用内部私有类,一个就是使用只有指定类才能调用的标志。我的实现就是采用后者。</P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE> /**<BR>  * 创建连接的工厂,只能让工厂调用<BR>  * @param factory 要调用工厂,并且一定被正确初始化<BR>  * @param param 连接参数<BR>  * @return 连接<BR>  */<BR> static public _Connection getConnection(ConnectionFactory factory, ConnectionParam param)<BR> {<BR>  if (factory.isCreate())//判断是否正确初始化的工厂<BR>  {<BR>   _Connection _conn = new _Connection(param);<BR>   return _conn;<BR>  }<BR>  else<BR>   return null;<BR> }<BR></CODE></PRE></TD></TR></TBODY></TABLE>

<UL>

<LI>提供良好的用户接口,简单实用</LI></UL>

<P>使用静态方法创建工厂,然后来得到连接,使用完全和普通的Connection方法一样,没有限制。同时为了方便,设置了连接参数类和工厂参数类。</P>

<UL>

<LI>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE> ConnectionParam param = new ConnectionParam(driver,url,user,password);<BR>  ConnectionFactory cf = null;//new ConnectionFactory(param, new FactoryParam());<BR>  try{<BR>   cf = new ConnectionFactory(param,new FactoryParam());<BR>   Connection conn1 = cf.getFreeConnection();<BR>   Connection conn2 = cf.getFreeConnection();<BR>   Connection conn3 = cf.getFreeConnection();<BR>   Statement stmt = conn1.createStatement();<BR>   ResultSet rs = stmt.executeQuery("select * from requests");<BR>   if (rs.next())<BR>   {<BR>    System.out.println("conn1 y");  <BR>   }<BR>   else<BR>   {<BR>    System.out.println("conn1 n");  <BR>   } <BR>   stmt.close();<BR>   conn1.close();  </CODE></PRE></TD></TR></TBODY></TABLE>

<LI>为了实现连接池的正常运作,使用了单态模式</LI></UL>

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE> /**<BR>  * 使用指定的参数创建一个连接池<BR>  */<BR> public ConnectionFactory(ConnectionParam param, FactoryParam fparam)<BR>  throws SQLException <BR> {<BR>  <A href="file://不">//不</A>允许参数为空<BR>  if ((param == null)||(fparam == null))<BR>   throw new SQLException("ConnectionParam和FactoryParam不能为空");<BR>  if (m_instance == null)<BR>  {<BR>   synchronized(ConnectionFactory.class){<BR>    if (m_instance == null)<BR>    {<BR>     <A href="file://new">//new</A> instance<BR>     <A href="file://参">//参</A>数定制<BR>     m_instance = new ConnectionFactory();<BR>     m_instance.connparam = param;<BR>     m_instance.MaxConnectionCount = fparam.getMaxConn();<BR>     m_instance.MinConnectionCount = fparam.getMinConn();<BR>     m_instance.ManageType = fparam.getType();<BR>     m_instance.isflag = true;<BR>     <A href="file://初">//初</A>始化,创建MinConnectionCount个连接<BR>     System.out.println("connection factory 创建!");<BR>     try{<BR>      for (int i=0; i < m_instance.MinConnectionCount; i++)<BR>      {<BR>       _Connection _conn = _Connection.getConnection(m_instance, m_instance.connparam);<BR>       if (_conn == null) continue;<BR>       System.out.println("connection创建");<BR>       m_instance.FreeConnectionPool.add(_conn);//加入空闲连接池<BR>       m_instance.current_conn_count ++;<BR>       <A href="file://标">//标</A>志是否支持事务<BR>       m_instance.supportTransaction = _conn.isSupportTransaction();    <BR>      }<BR>     }<BR>     catch(Exception e)<BR>     {<BR>      e.printStackTrace();<BR>     }<BR>     <A href="file://根">//根</A>据策略判断是否需要查询<BR>     if (m_instance.ManageType != 0)<BR>     {<BR>      Thread t = new Thread(new FactoryMangeThread(m_instance));<BR>      t.start();<BR>     } <BR>    }<BR>   }<BR>  }<BR> }<BR> </CODE></PRE></TD></TR></TBODY></TABLE></P>

<UL>

<LI>连接池的管理</LI></UL>

<P>对于连接池的管理,我是设想使用静态管理和动态管理两种策略,设置了最大限制,和恒定的连接数。使用了2个池,一个空闲池,一个使用池。静态就是使用的时候发现空闲连接不够再去检查。动态就是使用了一个线程定时检查。</P>

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE><CODE> //根据策略判断是否需要查询<BR>     if (m_instance.ManageType != 0)<BR>     {<BR>      Thread t = new Thread(new FactoryMangeThread(m_instance));<BR>      t.start();<BR>     }</CODE></PRE><PRE><CODE> //连接池调度线程<BR>public class FactoryMangeThread implements Runnable {<BR> ConnectionFactory cf = null;<BR> long delay = 1000;<BR> public FactoryMangeThread(ConnectionFactory obj)<BR> {<BR>  cf = obj;<BR> }<BR> /* (non-Javadoc)<BR>  * @see java.lang.Runnable#run()<BR>  */<BR> public void run() {<BR>  while(true){<BR>   try{<BR>    Thread.sleep(delay);<BR>   }<BR>   catch(InterruptedException e){}<BR>   System.out.println("eeeee");<BR>   <A href="file://判">//判</A>断是否已经关闭了工厂,那就退出监听<BR>   if (cf.isCreate())<BR>    cf.schedule();<BR>   else<BR>    System.exit(1);<BR>  }<BR> }<BR>}</CODE></PRE></TD></TR></TBODY></TABLE></P>

<P>最后给出完整的源代码:</P>

<P>

<HR>

<P></P>

<P>_Connectio.java</P>

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE>package scut.ailab.connectionpool;</PRE><PRE>import java.lang.reflect.*;<BR>import java.sql.*;</PRE><PRE>/**<BR> * @author youyongming<BR> * 定义数据库连接的代理类<BR> */<BR>public class _Connection implements InvocationHandler {<BR> <A href="file://定">//定</A>义连接<BR> private Connection conn = null;<BR> <A href="file://定">//定</A>义监控连接创建的语句<BR> private Statement statRef = null;<BR> private PreparedStatement prestatRef = null;<BR> <A href="file://是">//是</A>否支持事务标志<BR> private boolean supportTransaction = false;<BR> <A href="file://数">//数</A>据库的忙状态<BR> private boolean isFree = false;<BR> <A href="file://最">//最</A>后一次访问时间<BR> long lastAccessTime = 0;<BR> <A href="file://定">//定</A>义要接管的函数的名字<BR> String CREATESTATE = "createStatement";<BR> String CLOSE = "close";<BR> String PREPARESTATEMENT = "prepareStatement";<BR> String COMMIT = "commit";<BR> String ROLLBACK = "rollback";</PRE><PRE> /**<BR>  * 构造函数,采用私有,防止被直接创建<BR>  * @param param 连接参数<BR>  */<BR> private _Connection(ConnectionParam param) {<BR>  <A href="file://记">//记</A>录日至<BR>  <BR>  try{<BR>   <A href="file://创">//创</A>建连接<BR>   Class.forName(param.getDriver()).newInstance();<BR>   conn = DriverManager.getConnection(param.getUrl(),param.getUser(), param.getPassword());   <BR>   DatabaseMetaData dm = null;<BR>   dm = conn.getMetaData();<BR>   <A href="file://判">//判</A>断是否支持事务<BR>   supportTransaction = dm.supportsTransactions();<BR>  }<BR>  catch(Exception e)<BR>  {<BR>   e.printStackTrace();<BR>  }<BR> }</PRE><PRE><BR> /* (non-Javadoc)<BR>  * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])<BR>  */<BR> public Object invoke(Object proxy, Method method, Object[] args)<BR>  throws Throwable {<BR>   Object obj = null;<BR>   <A href="file://判">//判</A>断是否调用了close的方法,如果调用close方法则把连接置为无用状态<BR>   if(CLOSE.equals(method.getName()))<BR>   {<BR>    <A href="file://设">//设</A>置不使用标志<BR>    setIsFree(false);<BR>    <A href="file://检">//检</A>查是否有后续工作,清除该连接无用资源<BR>    if (statRef != null)<BR>     statRef.close();<BR>    if (prestatRef != null)<BR>     prestatRef.close();<BR>    return null;<BR>   }<BR>   <A href="file://判">//判</A>断是使用了createStatement语句<BR>   if (CREATESTATE.equals(method.getName()))<BR>   {<BR>    obj = method.invoke(conn, args);<BR>    statRef = (Statement)obj;//记录语句<BR>    return obj;<BR>   }<BR>   <A href="file://判">//判</A>断是使用了prepareStatement语句<BR>   if (PREPARESTATEMENT.equals(method.getName()))<BR>   {<BR>    obj = method.invoke(conn, args);<BR>    prestatRef = (PreparedStatement)obj;<BR>    return obj;<BR>   }<BR>   <A href="file://如">//如</A>果不支持事务,就不执行该事物的代码<BR>   if ((COMMIT.equals(method.getName())||ROLLBACK.equals(method.getName())) && (!isSupportTransaction()))<BR>    return null;   <BR>   obj = method.invoke(conn, args); <BR>   <A href="file://设">//设</A>置最后一次访问时间,以便及时清除超时的连接<BR>   lastAccessTime = System.currentTimeMillis();<BR>   return obj;<BR> }</PRE><PRE> /**<BR>  * 创建连接的工厂,只能让工厂调用<BR>  * @param factory 要调用工厂,并且一定被正确初始化<BR>  * @param param 连接参数<BR>  * @return 连接<BR>  */<BR> static public _Connection getConnection(ConnectionFactory factory, ConnectionParam param)<BR> {<BR>  if (factory.isCreate())//判断是否正确初始化的工厂<BR>  {<BR>   _Connection _conn = new _Connection(param);<BR>   return _conn;<BR>  }<BR>  else<BR>   return null;<BR> }<BR> <BR> public Connection getFreeConnection() {<BR>  <A href="file://返">//返</A>回数据库连接conn的接管类,以便截住close方法<BR>  Connection conn2 = (Connection)Proxy.newProxyInstance(<BR>   conn.getClass().getClassLoader(),<BR>   conn.getClass().getInterfaces(),this);<BR>  return conn2;<BR> }</PRE><PRE> /**<BR>  * 该方法真正的关闭了数据库的连接<BR>  * @throws SQLException<BR>  */<BR> void close() throws SQLException{<BR>  <A href="file://由">//由</A>于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接<BR>  conn.close();<BR> }<BR>   <BR> public void setIsFree(boolean value)<BR> {<BR>  isFree = value;<BR> }<BR> <BR> public boolean isFree() {<BR>  return isFree;<BR> } <BR> /**<BR>  * 判断是否支持事务<BR>  * @return boolean<BR>  */<BR> public boolean isSupportTransaction() {<BR>  return supportTransaction;<BR> } <BR>}<BR></PRE></TD></TR></TBODY></TABLE></P>

<P>

<HR>

ConnectionFactory.java

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE> package scut.ailab.connectionpool;</PRE><PRE>/**<BR> * @author youyongming<BR> *<BR> */<BR>import java.util.LinkedHashSet;<BR>import java.sql.*;<BR>import java.util.Iterator;</PRE><PRE>public class ConnectionFactory {<BR> private static ConnectionFactory m_instance = null;<BR> <A href="file://在">//在</A>使用的连接池<BR> private LinkedHashSet ConnectionPool = null;<BR> <A href="file://空">//空</A>闲连接池<BR> private LinkedHashSet FreeConnectionPool = null;<BR> <A href="file://最">//最</A>大连接数<BR> private int MaxConnectionCount = 4;<BR> <A href="file://最">//最</A>小连接数<BR> private int MinConnectionCount = 2;<BR> <A href="file://当">//当</A>前连接数<BR> private int current_conn_count = 0;<BR> <A href="file://连">//连</A>接参数<BR> private ConnectionParam connparam = null;<BR> <A href="file://是">//是</A>否创建工厂的标志<BR> private boolean isflag = false;<BR> <A href="file://是">//是</A>否支持事务<BR> private boolean supportTransaction = false;<BR> <A href="file://定">//定</A>义管理策略<BR> private int ManageType = 0;</PRE><PRE> private ConnectionFactory() {<BR>  ConnectionPool = new LinkedHashSet();<BR>  FreeConnectionPool = new LinkedHashSet();<BR> }<BR> <BR> /**<BR>  * 使用指定的参数创建一个连接池<BR>  */<BR> public ConnectionFactory(ConnectionParam param, FactoryParam fparam)<BR>  throws SQLException <BR> {<BR>  <A href="file://不">//不</A>允许参数为空<BR>  if ((param == null)||(fparam == null))<BR>   throw new SQLException("ConnectionParam和FactoryParam不能为空");<BR>  if (m_instance == null)<BR>  {<BR>   synchronized(ConnectionFactory.class){<BR>    if (m_instance == null)<BR>    {<BR>     <A href="file://new">//new</A> instance<BR>     <A href="file://参">//参</A>数定制<BR>     m_instance = new ConnectionFactory();<BR>     m_instance.connparam = param;<BR>     m_instance.MaxConnectionCount = fparam.getMaxConn();<BR>     m_instance.MinConnectionCount = fparam.getMinConn();<BR>     m_instance.ManageType = fparam.getType();<BR>     m_instance.isflag = true;<BR>     <A href="file://初">//初</A>始化,创建MinConnectionCount个连接<BR>     System.out.println("connection factory 创建!");<BR>     try{<BR>      for (int i=0; i < m_instance.MinConnectionCount; i++)<BR>      {<BR>       _Connection _conn = _Connection.getConnection(m_instance, m_instance.connparam);<BR>       if (_conn == null) continue;<BR>       System.out.println("connection创建");<BR>       m_instance.FreeConnectionPool.add(_conn);//加入空闲连接池<BR>       m_instance.current_conn_count ++;<BR>       <A href="file://标">//标</A>志是否支持事务<BR>       m_instance.supportTransaction = _conn.isSupportTransaction();    <BR>      }<BR>     }<BR>     catch(Exception e)<BR>     {<BR>      e.printStackTrace();<BR>     }<BR>     <A href="file://根">//根</A>据策略判断是否需要查询<BR>     if (m_instance.ManageType != 0)<BR>     {<BR>      Thread t = new Thread(new FactoryMangeThread(m_instance));<BR>      t.start();<BR>     } <BR>    }<BR>   }<BR>  }<BR> }<BR> <BR> /**<BR>  * 标志工厂是否已经创建<BR>  * @return boolean<BR>  */ <BR> public boolean isCreate()<BR> {<BR>  return m_instance.isflag;<BR> }<BR> <BR> /**<BR>  * 从连接池中取一个空闲的连接<BR>  * @return Connection<BR>  * @throws SQLException<BR>  */<BR> public synchronized Connection getFreeConnection() <BR>  throws SQLException<BR> {<BR>  Connection conn = null;<BR>  <A href="file://获">//获</A>取空闲连接<BR>  Iterator iter = m_instance.FreeConnectionPool.iterator();<BR>  while(iter.hasNext()){<BR>   _Connection _conn = (_Connection)iter.next();<BR>   <A href="file://找">//找</A>到未用连接<BR>   if(!_conn.isFree()){<BR>    conn = _conn.getFreeConnection();<BR>    _conn.setIsFree(true);<BR>    <A href="file://移">//移</A>出空闲区<BR>    m_instance.FreeConnectionPool.remove(_conn);<BR>    <A href="file://加">//加</A>入连接池 <BR>    m_instance.ConnectionPool.add(_conn);   <BR>    break;<BR>   }<BR>  }<BR>  <A href="file://检">//检</A>查空闲池是否为空<BR>  if (m_instance.FreeConnectionPool.isEmpty())<BR>  {<BR>   <A href="file://再">//再</A>检查是否能够分配<BR>   if (m_instance.current_conn_count < m_instance.MaxConnectionCount)<BR>   {<BR>   <A href="file://新">//新</A>建连接到空闲连接池<BR>    int newcount = 0 ;<BR>    <A href="file://取">//取</A>得要建立的数目<BR>    if (m_instance.MaxConnectionCount - m_instance.current_conn_count >=m_instance.MinConnectionCount)<BR>    {<BR>     newcount = m_instance.MinConnectionCount;<BR>    }<BR>    else<BR>    {<BR>     newcount = m_instance.MaxConnectionCount - m_instance.current_conn_count;<BR>    }<BR>    /<A href="file://创">/创</A>建连接<BR>    for (int i=0;i <newcount; i++)<BR>    {<BR>     _Connection _conn = _Connection.getConnection(m_instance, m_instance.connparam);<BR>     m_instance.FreeConnectionPool.add(_conn);<BR>     m_instance.current_conn_count ++;<BR>    }<BR>   }<BR>   else<BR>   {//如果不能新建,检查是否有已经归还的连接<BR>    iter = m_instance.ConnectionPool.iterator();<BR>    while(iter.hasNext()){<BR>     _Connection _conn = (_Connection)iter.next();<BR>     if(!_conn.isFree()){<BR>      conn = _conn.getFreeConnection();<BR>      _conn.setIsFree(false);<BR>      m_instance.ConnectionPool.remove(_conn); <BR>      m_instance.FreeConnectionPool.add(_conn);   <BR>      break;<BR>     }<BR>    }    <BR>   }<BR>  }//if (FreeConnectionPool.isEmpty())<BR> <A href="file://再">//再</A>次检查是否能分配连接<BR>  if(conn == null){<BR>   iter = m_instance.FreeConnectionPool.iterator();<BR>   while(iter.hasNext()){<BR>    _Connection _conn = (_Connection)iter.next();<BR>    if(!_conn.isFree()){<BR>     conn = _conn.getFreeConnection();<BR>     _conn.setIsFree(true);<BR>     m_instance.FreeConnectionPool.remove(_conn); <BR>     m_instance.ConnectionPool.add(_conn);   <BR>     break;<BR>    }<BR>   }<BR>   if(conn == null)//如果不能则说明无连接可用<BR>    throw new SQLException("没有可用的数据库连接");<BR>  }<BR>  System.out.println("get connection");<BR>  return conn;<BR> }<BR> <BR> /**<BR>  * 关闭该连接池中的所有数据库连接<BR>  * @throws SQLException<BR>  */<BR> public synchronized void close() throws SQLException<BR> {<BR>  this.isflag = false;<BR>  SQLException excp = null;<BR>  <A href="file://关">//关</A>闭空闲池<BR>  Iterator iter = m_instance.FreeConnectionPool.iterator();<BR>  while(iter.hasNext()){<BR>   try{<BR>    ((_Connection)iter.next()).close();<BR>    System.out.println("close connection:free");<BR>    m_instance.current_conn_count --;<BR>   }catch(Exception e){<BR>    if(e instanceof SQLException)<BR>     excp = (SQLException)e;<BR>   }<BR>  }<BR>  <A href="file://关">//关</A>闭在使用的连接池<BR>  iter = m_instance.ConnectionPool.iterator();<BR>  while(iter.hasNext()){<BR>   try{<BR>    ((_Connection)iter.next()).close();<BR>    System.out.println("close connection:inused");<BR>    m_instance.current_conn_count --;<BR>   }catch(Exception e){<BR>    if(e instanceof SQLException)<BR>     excp = (SQLException)e;<BR>   }<BR>  }  <BR>  if(excp != null)<BR>   throw excp;<BR> } <BR> <BR> /**<BR>  * 返回是否支持事务<BR>  * @return boolean<BR>  */<BR> public boolean isSupportTransaction() {<BR>  return m_instance.supportTransaction;<BR> }  <BR> /**<BR>  * 连接池调度管理<BR>  *<BR>  */<BR> public void schedule()<BR> {<BR>  Connection conn = null;<BR>  <A href="file://再">//再</A>检查是否能够分配<BR>  Iterator iter = null;<BR>  <A href="file://检">//检</A>查是否有已经归还的连接<BR>  {<BR>   iter = m_instance.ConnectionPool.iterator();<BR>   while(iter.hasNext()){<BR>    _Connection _conn = (_Connection)iter.next();<BR>    if(!_conn.isFree()){<BR>     conn = _conn.getFreeConnection();<BR>     _conn.setIsFree(false);<BR>     m_instance.ConnectionPool.remove(_conn); <BR>     m_instance.FreeConnectionPool.add(_conn);   <BR>     break;<BR>    }<BR>   }    <BR>  }<BR>  if (m_instance.current_conn_count < m_instance.MaxConnectionCount)<BR>  {<BR>   <A href="file://新">//新</A>建连接到空闲连接池<BR>   int newcount = 0 ;<BR>   <A href="file://取">//取</A>得要建立的数目<BR>   if (m_instance.MaxConnectionCount - m_instance.current_conn_count >=m_instance.MinConnectionCount)<BR>   {<BR>    newcount = m_instance.MinConnectionCount;<BR>   }<BR>   else<BR>   {<BR>    newcount = m_instance.MaxConnectionCount - m_instance.current_conn_count;<BR>   }<BR>   <A href="file://创">//创</A>建连接<BR>   for (int i=0;i <newcount; i++)<BR>   {<BR>    _Connection _conn = _Connection.getConnection(m_instance, m_instance.connparam);<BR>    m_instance.FreeConnectionPool.add(_conn);<BR>    m_instance.current_conn_count ++;<BR>   }<BR>  }<BR> }<BR>}</PRE></TD></TR></TBODY></TABLE></P>

<P>

<HR>

ConnectionParam.java

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE> package scut.ailab.connectionpool;</PRE><PRE>import java.io.Serializable;</PRE><PRE>/**<BR> * @author youyongming<BR> * 实现数据库连接的参数类<BR> */<BR>public class ConnectionParam implements Serializable {<BR> private String driver;    <A href="file://数">//数</A>据库驱动程序<BR> private String url;   <A href="file://数">//数</A>据连接的URL<BR> private String user;    <A href="file://数">//数</A>据库用户名<BR> private String password;   <A href="file://数">//数</A>据库密码<BR> <BR> /**<BR>  * 唯一的构造函数,需要指定连接的四个必要参数<BR>  * @param driver 数据驱动<BR>  * @param url  数据库连接url<BR>  * @param user  用户名<BR>  * @param password 密码<BR>  */<BR> public ConnectionParam(String driver,String url,String user,String password)<BR> {<BR>  this.driver = driver;<BR>  this.url = url;<BR>  this.user = user;<BR>  this.password = password;<BR> }</PRE><PRE> public String getDriver() {<BR>  return driver;<BR> }</PRE><PRE> public String getPassword() {<BR>  return password;<BR> }</PRE><PRE> public String getUrl() {<BR>  return url;<BR> }</PRE><PRE> public String getUser() {<BR>  return user;<BR> }</PRE><PRE> public void setDriver(String driver) {<BR>  this.driver = driver;<BR> }</PRE><PRE> public void setPassword(String password) {<BR>  this.password = password;<BR> }</PRE><PRE> public void setUrl(String url) {<BR>  this.url = url;<BR> }</PRE><PRE> public void setUser(String user) {<BR>  this.user = user;<BR> }</PRE><PRE> /**<BR>  * @see java.lang.Object#clone()<BR>  */<BR> public Object clone(){<BR>  ConnectionParam param = new ConnectionParam(driver,url,user,password);<BR>  return param;<BR> }</PRE><PRE> /**<BR>  * @see java.lang.Object#equals(java.lang.Object)<BR>  */<BR> public boolean equals(Object obj) {<BR>  if(obj instanceof ConnectionParam){<BR>   ConnectionParam param = (ConnectionParam)obj;<BR>   return ((driver.compareToIgnoreCase(param.getDriver()) == 0)&&<BR>   (url.compareToIgnoreCase(param.getUrl()) == 0)&&<BR>   (user.compareToIgnoreCase(param.getUser()) == 0)&&<BR>   (password.compareToIgnoreCase(param.getPassword()) == 0));<BR>  }<BR>  return false;<BR> }<BR>}<BR></PRE></TD></TR></TBODY></TABLE></P>

<P>

<HR>

FactoryMangeThread.java

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE> /*<BR> * Created on 2003-5-13<BR> *<BR> * To change the template for this generated file go to<BR> * Window>Preferences>Java>Code Generation>Code and Comments<BR> */<BR>package scut.ailab.connectionpool;</PRE><PRE>/**<BR> * @author youyongming<BR> *<BR> */<BR><A href="file://连">//连</A>接池调度线程<BR>public class FactoryMangeThread implements Runnable {<BR> ConnectionFactory cf = null;<BR> long delay = 1000;<BR> public FactoryMangeThread(ConnectionFactory obj)<BR> {<BR>  cf = obj;<BR> }<BR> /* (non-Javadoc)<BR>  * @see java.lang.Runnable#run()<BR>  */<BR> public void run() {<BR>  while(true){<BR>   try{<BR>    Thread.sleep(delay);<BR>   }<BR>   catch(InterruptedException e){}<BR>   System.out.println("eeeee");<BR>   <A href="file://判">//判</A>断是否已经关闭了工厂,那就退出监听<BR>   if (cf.isCreate())<BR>    cf.schedule();<BR>   else<BR>    System.exit(1);<BR>  }<BR> }<BR>}<BR></PRE></TD></TR></TBODY></TABLE></P>

<P>

<HR>

FactoryParam.java

<P>

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE> /*<BR> * Created on 2003-5-13<BR> *<BR> * To change the template for this generated file go to<BR> * Window>Preferences>Java>Code Generation>Code and Comments<BR> */<BR>package scut.ailab.connectionpool;</PRE><PRE>/**<BR> * @author youyongming<BR> *<BR> */<BR><A href="file://连">//连</A>接池工厂参数<BR>public class FactoryParam {<BR> <A href="file://最">//最</A>大连接数<BR> private int MaxConnectionCount = 4;<BR> <A href="file://最">//最</A>小连接数<BR> private int MinConnectionCount = 2; <BR> <A href="file://回">//回</A>收策略<BR> private int ManageType = 0;<BR> <BR> public FactoryParam() {<BR> }<BR> <BR> /**<BR>  * 构造连接池工厂参数的对象<BR>  * @param max 最大连接数<BR>  * @param min 最小连接数<BR>  * @param type 管理策略<BR>  */<BR> public FactoryParam(int max, int min, int type)<BR> {<BR>  this.ManageType = type;<BR>  this.MaxConnectionCount = max;<BR>  this.MinConnectionCount = min;<BR> }<BR> <BR> /**<BR>  * 设置最大的连接数<BR>  * @param value<BR>  */<BR> public void setMaxConn(int value)<BR> {<BR>  this.MaxConnectionCount = value;<BR> }<BR> /**<BR>  * 获取最大连接数<BR>  * @return<BR>  */<BR> public int getMaxConn()<BR> {<BR>  return this.MaxConnectionCount;<BR> }<BR> /**<BR>  * 设置最小连接数<BR>  * @param value<BR>  */<BR> public void setMinConn(int value)<BR> {<BR>  this.MinConnectionCount = value;<BR> }<BR> /**<BR>  * 获取最小连接数<BR>  * @return<BR>  */<BR> public int getMinConn()<BR> {<BR>  return this.MinConnectionCount;<BR> }<BR> public int getType()<BR> {<BR>  return this.ManageType;<BR> }<BR>}</PRE></TD></TR></TBODY></TABLE></P>

<P>

<HR>

testmypool.java

<TABLE bgColor=#cccccc border=1 cellPadding=5 cellSpacing=0 width="100%">

<TBODY>

<TR>

<TD><PRE> /*<BR> * Created on 2003-5-13<BR> *<BR> * To change the template for this generated file go to<BR> * Window>Preferences>Java>Code Generation>Code and Comments<BR> */<BR>package scut.ailab.connectionpool;</PRE><PRE>/**<BR> * @author youyongming<BR> *<BR> */<BR>import java.sql.*;</PRE><PRE>public class testmypool {</PRE><PRE> public void test1()<BR> {<BR>  String user = "DevTeam";<BR>  String password = "DevTeam";<BR>  String driver = "sun.jdbc.odbc.JdbcOdbcDriver";<BR>  String url = "jdbc:odbc:gfqh2";<BR>  ConnectionParam param = new ConnectionParam(driver,url,user,password);<BR>  ConnectionFactory cf = null;//new ConnectionFactory(param, new FactoryParam());<BR>  try{<BR>   cf = new ConnectionFactory(param,new FactoryParam());<BR>   Connection conn1 = cf.getFreeConnection();<BR>   Connection conn2 = cf.getFreeConnection();<BR>   Connection conn3 = cf.getFreeConnection();<BR>   Statement stmt = conn1.createStatement();<BR>   ResultSet rs = stmt.executeQuery("select * from requests");<BR>   if (rs.next())<BR>   {<BR>    System.out.println("conn1 y");  <BR>   }<BR>   else<BR>   {<BR>    System.out.println("conn1 n");  <BR>   } <BR>   stmt.close();<BR>   conn1.close();  <BR>   Connection conn4 = cf.getFreeConnection();<BR>   Connection conn5 = cf.getFreeConnection();<BR>   stmt = conn5.createStatement();<BR>   rs = stmt.executeQuery("select * from requests");<BR>   if (rs.next())<BR>   {<BR>    System.out.println("conn5 y");  <BR>   }<BR>   else<BR>   {<BR>    System.out.println("conn5 n");  <BR>   } <BR>   conn2.close();<BR>   conn3.close();<BR>   conn4.close();<BR>   conn5.close();<BR>   }<BR>  catch(Exception e)<BR>  {<BR>   e.printStackTrace();<BR>  }<BR>  finally{<BR>   try{<BR>    cf.close();<BR>   }<BR>   catch(Exception e)<BR>   {<BR>    e.printStackTrace();<BR>   }<BR>  } <BR> }<BR> public static void main(String[] args) {<BR>  String user = "DevTeam";<BR>  String password = "DevTeam";<BR>  String driver = "sun.jdbc.odbc.JdbcOdbcDriver";<BR>  String url = "jdbc:odbc:gfqh2";<BR>  ConnectionParam param = new ConnectionParam(driver,url,user,password);<BR>  ConnectionFactory cf = null;//new ConnectionFactory(param,new FactoryParam());<BR>  try{<BR>   cf = new ConnectionFactory(param,new FactoryParam());<BR>   ConnectionFactory cf1= new ConnectionFactory(param,new FactoryParam());<BR>   Connection conn1 = null;<BR>   long time = System.currentTimeMillis();<BR>   for (int i=0; i <10;i++)<BR>   {<BR>    conn1 = cf.getFreeConnection();<BR>    Statement stmt = conn1.createStatement();<BR>    ResultSet rs = stmt.executeQuery("select * from requests");<BR>    if (rs.next())<BR>    {<BR>     System.out.println("conn1 y");  <BR>    }<BR>    else<BR>    {<BR>     System.out.println("conn1 n");  <BR>    } <BR>    conn1.close();  <BR>   }<BR>   System.out.println("pool:" + (System.currentTimeMillis()-time));<BR>   time = System.currentTimeMillis();<BR>   Class.forName(param.getDriver()).newInstance();<BR>   for (int i=0; i <10;i++)<BR>   {<BR>    conn1 = DriverManager.getConnection(param.getUrl(),param.getUser(), param.getPassword());   <BR>    Statement stmt = conn1.createStatement();<BR>    ResultSet rs = stmt.executeQuery("select * from requests");<BR>    if (rs.next())<BR>    {<BR>     System.out.println("conn1 y");  <BR>    }<BR>    else<BR>    {<BR>     System.out.println("conn1 n");  <BR>    } <BR>    conn1.close();  <BR>   }   <BR>   System.out.println("no pool:" + (System.currentTimeMillis()-time));<BR>  }<BR>  catch(Exception e)<BR>  {<BR>   e.printStackTrace();<BR>  }<BR>  finally{<BR>   try{<BR>    cf.close();<BR>   }<BR>   catch(Exception e)<BR>   {<BR>    e.printStackTrace();<BR>   }<BR>  }<BR> }<BR>}<BR></PRE></TD></TR></TBODY></TABLE>

<UL>

<LI>关于作者:游永明,人工智能实验室在读研究生,爱好Linux和Java的开发,研究方向是时态数据库。希望能和大家进行探讨和交流,<A href="mailto:chinascutface@hotmail.com">chinascutface@hotmail.com</A></LI></UL><br>

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 数据库连接池java实现小结

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.0023