qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

JDBC 数据库连接池

通常java应用程序在访问数据库时,直接创建一个数据库连接,使用完毕后释放连接。

  如图:

  当数据库连接量小的时候这样做并无不妥,但若在访问量大的时候就显得低效了,如某网站一天访问量在1000万次,那么在这一天web应用程序与数据库就要进行等量的连接和断开操作。

  为了解决这个问题,引入了数据库连接池技术(个人认为数据库连接池技术是为解决这个问题的),它是批量创建一批数据库连接,放到一个数据库连接池,在需要数据库连接时,就像这个池子拿,用完后则将数据库连接还回池子,数据库连接的维护由池负责维护,这样不管访问量如何大,程序与数据库的连接是不变的,不过当数据库连接池的连接已用完,这时又有新的连接请求,此时池中已无连接,那么就只能等待或返回异常,所以数据库连接池一次批量创建的连接数量应根据实际情况来设置。

  采用数据库连接池技术如图:

  根据数据库连接池工作原理来手动写一个数据库连接池,实现基本功能。

  1.从池中拿出数据库连接

  2.用完后还回池里

  3.数据库连接的存放与维护

 Code

package xgn.jdbc;

import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
import java.util.Properties;

/***
 * 数据库连接池实现类
 * @author dream
 *
 */
public class JDBCPool {
 //存放连接的集合
 private static LinkedList<Connection> dblist=new LinkedList<Connection>();
 //连接池容量
 private static final int number=100;
 static{
  try{
   Properties config=new Properties();
   InputStream in= JDBCPool.class.getClassLoader().getResourceAsStream("config.properties");
   config.load(in);
   for(int i=0;i<number;i++){
    Connection cn= DriverManager.getConnection(config.getProperty("Connstr"),config.getProperty("user"),config.getProperty("pwd"));
    ConnectionProxy conn=new ConnectionProxy(cn);
    Connection proxycn=conn.getConnectionProxy(cn,new Class[]{Connection.class},conn);
    dblist.addFirst(proxycn);
   } 
  }catch(Exception ex){
   throw new RuntimeException(ex);
  }
 }
 public static void recoverConnection(Connection cn){
  dblist.addFirst(cn);
 }
 public static Connection getConnection(){
  if(dblist.size()<=0){
   throw new RuntimeException("数据库连接池无数据库连接!");
  }
  return dblist.removeFirst();
 }
 public static int getConnectionNumber(){
  return dblist.size();
 }
 
 /***
  * 数据库连接代理类
  * @author dream
  *
  */
 public static class ConnectionProxy implements InvocationHandler {
  private Object obj=null;
  private Object proxyobj=null;
  @Override
  public Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable {
   Object ret=null;//方法返回值
   if(arg1.getName()=="close"){
    System.out.println("close");
    JDBCPool.recoverConnection((Connection)this.proxyobj);
    return ret;
   }
   ret=arg1.invoke(this.obj, arg2);
   return ret;
  }
  public ConnectionProxy(Connection cn){
   this.obj=cn;
  }
  
  public Connection getConnectionProxy(Connection cn,Class[] cls,InvocationHandler h){
   this.proxyobj= Proxy.newProxyInstance(cn.getClass().getClassLoader(),cls,h);
   return (Connection)this.proxyobj;
  }
  
 }
}

  常用的数据库连接池有:DBCP、tomcat 的数据库连接池(内部也是DBCP)、C3P0等。

posted on 2013-08-09 09:27 顺其自然EVO 阅读(207) 评论(0)  编辑  收藏 所属分类: 测试学习专栏


只有注册用户登录后才能发表评论。


网站导航:
 
<2013年8月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜