网页功能: 加入收藏 设为首页 网站搜索  
数据库连接池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实现小结
本类热点文章
  Java读取文件中含有中文的解决办法
  Java读取文件中含有中文的解决办法
  简单加密/解密方法包装, 含encode(),de..
  EJB 3.0规范全新体验
  java简单的获取windows系统网卡mac地址
  让Java程序带着JRE一起上路
  抢先体验"野马"J2SE6.0
  Java连接各种数据库的实例
  Java连接各种数据库的实例
  JAVA的XML编程实例解析
  Java学习从入门到精通(附FAQ)
  新手必读:Java学习的捷径
最新分类信息我要发布 
最新招聘信息

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