J2EE学习:DAO层-数据源封装

本文介绍了一种基于DriverPool类的数据源封装方法,该方法通过维护一个数据库连接池,实现了连接的有效管理和复用,同时引入了PoolMonitor后台线程来监控连接状态并确保连接池始终处于最优状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据源封装

 

DriverPool类的实现

实现思路:根据一个池的阈值n大小,创建n条数据库连接;把这些连接保存在内存池中,当有连接请求,就从池中连接给用户;考虑到无效连接的回收问题:如果采用--池中没有可用的连接,则重新创建n个连接;改进的方法是:建立一个后台线程,专门负责连接池的监控。实时回收无效连接和建立新连接,保证连接池任何时候都有足够的资源。

类图:


PoolMonitor为一个后台线程,负责无效连接的回收和新连接的创建工作;

为了识别一条连接是否有效,建立了PooledConnection值对象类;

 

//**例子是从一本书上的,貌似是不能直接跑出来的;主要是觉得可以学习下封装思想****//

 

packagecom.beetle.framework.persistence.db.ds;

 

import java.sql.*;

import java.util.*;

import javax.transaction.*;

 

importcom.beetle.framework.persistence.db.*;

 

public class DriverPool

   implements IConnPool {

 private String driverName;

 private String conURL;

 private String username;

 private String password;

 private int min, max;

 //private int poolSize;

 Vector conPool;  //用一个Vector来连接存储池中的值

 private Driver drv;

 

  /**

   *Constructor creates a JDBC connection using given parameters

   *@param databaseType

   *@param driverName

   *@param conURL

   *@param username

   *@param password

   */

 public DriverPool(int max, int min,

                    String driverName,

                    String conURL,

                    String username,

                    String password) {

   this.driverName = driverName;

   this.conURL = conURL;

   this.username = username;

   this.password = password;

   //this.poolSize = max; //

   //this.poolSize = min;

   this.max = max;

   this.min = min;

   conPool = new Vector();

   addConnectionsToPool(this.min);

   new PoolMonitor().startNow();

  }

 

  /**

   *Constructor uses the given connection (con) as its connection. Use thisconstructor if you

   *want to get your connections from some custom code or from a connection pool.

   *@param con

   *@param dbType

   */

 public DriverPool(Connection con) {

   conPool = new Vector();

   PooledConnection pc = new PooledConnection(con, true);

   conPool.add(pc);

   new PoolMonitor().startNow();

  }

 

  /**往

   *Creates database connection(s) and adds them to the pool.

   *@param numPooledCon

   *@param driverName

   *@param conURL

   *@param username

   *@param password

   */

 private synchronized void addConnectionsToPool(int numPooledCon) {

   try {

     if (drv == null) {

       drv = (Driver) Class.forName(driverName).newInstance();

       DriverManager.registerDriver(drv);

     }

     for (int i = 0; i < numPooledCon; i++) {

       Connection con = DriverManager.getConnection(conURL, username,password);

       PooledConnection pc = new PooledConnection(con, true);

       conPool.add(pc);

     }

    }

   catch (Exception e) {

     e.printStackTrace();

    }

  }

 

 //synchronized

 private void moniPool() {

   removeAnyClosedConnections();

   if (this.conPool.size() < this.min) {

     int x = (this.max - this.min) / 2;

     int j = this.min - this.conPool.size();

     if (x > 0) {

       if (x + j > this.max) {

         this.addConnectionsToPool(x);

       }

       else {

         this.addConnectionsToPool(x + j);

       }

     }

     else {

       this.addConnectionsToPool(j);

     }

    }

  }

 

 private synchronized void removeAnyClosedConnections() {

   try {

     boolean done = false;

     while (!done) {

       done = true;

       for (int i = 0; i < conPool.size(); i++) {

         PooledConnection pc = (PooledConnection) conPool.get(i);

         if (pc.getConnection().isClosed()) { //remove any closed connections

           conPool.remove(i);

           done = false;

           break;

         }

       }

     }

    }

   catch (SQLException e) {

     e.printStackTrace();

    }

  }

 

  /**

   *Gets available connection from the pool

   *@return Connection

   */

 public synchronized Connection getConnection() {

   //if any connections have been closed, remove them from the pool beforewe get the

   //next available connection

   //removeAnyClosedConnections();

   for (int i = 0; i < conPool.size(); i++) {

     PooledConnection pc = (PooledConnection) conPool.get(i);

     if (pc.isAvailable()) {

       pc.setAvailable(false); //使用过一次就设置为不可用

       return pc.getConnection();

     }

    }

   //removeAnyClosedConnections();

   //didn't find a connection, so add some(size) to the pool

   addConnectionsToPool(1);

   PooledConnection pc = (PooledConnection) conPool.get(conPool.size() -1);

   if (pc.isAvailable()) {

     pc.setAvailable(false);

    }

   return pc.getConnection();

  }

 

  /**

   *Closes all connections in the connection pool.

   */

 public void closeAllConnections() {

   for (int i = 0; i < conPool.size(); i++) {

     PooledConnection pc = (PooledConnection) conPool.get(i);

     closeConnection(pc.getConnection());

    }

   conPool.clear(); //remove all PooledConnections from list

  }

 

  /**

   *method closes the given connection

   *@param con connection to close

   *@param dbType type of database (used to throw appropriate exception)

   */

 private void closeConnection(Connection con) {

   try {

     if (con != null) {

       con.close();

     }

    }

   catch (SQLException e) {

     e.printStackTrace();

    }

  }

 

 public int getPoolType() {

   return this.POOL_TYPE_DRIVER; //driver type

  }

 

 public void setTransactionManager(TransactionManager tm) {

   throw new com.beetle.framework.AppRuntimeException("do notsupport");

  }

 

 private class PoolMonitor

     extends com.beetle.framework.appsrv.AppRunnable {

   private int time;

   public PoolMonitor() {

     super();

     time = 1000;

    }

 

   protected void end() {

     closeAllConnections();

    }

 

   public void run() {

     while (!this.getStopFlag()) {

       moniPool();

       sleep(time);

     }

    }

 

  }

}

 

class PooledConnection {

 private Connection con;

 private boolean available;

 PooledConnection(Connection con, boolean available) {

   this.con = con;

   this.available = available;

  }

 

 Connection getConnection() {

   return con;

  }

 

 boolean isAvailable() {

   return available;

  }

 

 void setAvailable(boolean available) {

   this.available = available;

  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值