数据源封装
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;
}
}