写了一个简单的数据库连接池,请帮忙看一下

我是一个新手,第一次发帖,以前都是看别人的帖子。
我写了一个简单的数据库连接池实现,感觉有很多欠缺的地方,希望各位指点一下。十分感谢。
有四个类:
(1)连接池配置对象 Config
(2)连接池主类 ConnectionPool
(3)Properties读取类 PropertyReader
(4)异常类 DBPoolException


ConnectionPool.java

public class ConnectionPool {

private static Logger logger = Logger.getLogger(ConnectionPool.class);
//当前已用连接数
private static volatile int curConnections = 0;

private static Config config = null;

//初始化成功标志
private static boolean initFlag = false;

private static volatile Stack<Connection> conns;
static {
PropertyReader pr = null;

try {
pr = new PropertyReader("pool-config.properties");
config = new Config();
//设置数据库驱动
config.setDriver(pr.getValue("driver"));
//url
config.setUrl(pr.getValue("url"));
//uername
config.setUsername(pr.getValue("username"));
//password
config.setPassword(pr.getValue("password"));
//最大连接数
if(pr.getValue("maxConnections") != null){
config.setMaxConnections(Integer.valueOf(pr.getValue("maxConnections")));
}
//初始化时最小连接数
if(pr.getValue("minConnections") != null){
config.setMinConnections(Integer.valueOf(pr.getValue("minConnections")));
}
//返还连接时是否提交
if(pr.getValue("autoCommitOnClose") != null){
config.setAutoCommitOnClose(Boolean.valueOf(pr.getValue("autoCommitOnClose")));
}
//当连接池用完时客户端调用getConn()后等待获取新连接的时间
//Default: (100毫秒)
if(pr.getValue("checkoutTimeout") != null){
config.setCheckoutTimeout(Integer.valueOf(pr.getValue("checkoutTimeout")));
}
//当没有可用链接时,尝试获取链接的次数
if(pr.getValue("checkTimes") != null){
config.setCheckTimes(Integer.valueOf(pr.getValue("checkTimes")));
}
initPool();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}

}
/**
* 隐藏构造函数
*/
private ConnectionPool(){

}

/**
* 初始化连接池 保存minConnections个链接
* @throws SQLException
* @throws ClassNotFoundException
*/
private static synchronized void initPool() throws SQLException, ClassNotFoundException{
conns = new Stack<Connection>();
Class.forName(config.getDriver());
for(int i = 0 ; i < config.getMinConnections() ; i++){
Connection conn = newConnection();
conns.push(conn);
}
initFlag = true;
}
/**
* 获取一个可用链接
* @return
* @throws SQLException
* @throws InterruptedException
* @throws DBPoolException
* @throws Exception
*/
public static Connection getConn() throws SQLException, InterruptedException, DBPoolException {
Connection conn = null;
if (initFlag) {
synchronized (conns) {
// 循环次数
int times = 0;
while (null == conn && times < config.getCheckTimes() + 1) {
times++;
// 如果未达到最大链接
if (curConnections < config.getMaxConnections()) {
// 栈中未空
if (!conns.isEmpty()) {
conn = conns.pop();
// 如果返回的链接不可用
if (null == conn || conn.isClosed()) {
conn = newConnection();
}
// 栈中空了
} else {
conn = newConnection();
}
} else {
conns.wait(config.getCheckoutTimeout());
}

}
if(null == conn){
logger.warn("获取链接超时!!!!!");
throw new DBPoolException("获取链接超时!!!!!");
}else{
curConnections++;
conns.notifyAll();
}

}
} else {
logger.error("连接池初始化失败!!!!");
throw new DBPoolException("连接池初始化失败!!!!");
}

return conn;
}

/**
* 归还一个链接
* @param conn
* @throws SQLException
* @throws InterruptedException
*/
public static void returnConn(Connection conn) throws SQLException, InterruptedException {
synchronized (conns) {
if (null != conn && !conn.isClosed()) {
// 如果设置归还前自动提交为真
if (config.isAutoCommitOnClose()) {
conn.commit();
} else {
conn.rollback();
}
}
int times = 0;
//尝试归还5次 如果归还失败则关闭连接
while (times < 6) {
times++;
if (curConnections > 0 && curConnections <= config.getMaxConnections()) {
conns.push(conn);
curConnections--;
break;
} else if (curConnections == 0) {
conns.wait(1000);
} else {
if(conn!=null && !conn.isClosed())
conn.close();
curConnections--;
break;
}
}
if(times == 5 && conn != null && !conn.isClosed()){
conn.close();
}


conns.notifyAll();
}
}

/**
* 简单的创建一个链接
* @return
* @throws SQLException
*/
private static Connection newConnection() throws SQLException{
return DriverManager.getConnection(config.getUrl(),config.getUsername(),config.getPassword());
}
/**
* 获取已使用的连接数
* @return
*/
public static int getCurConnections() {
return curConnections;
}

}



Config.java

public class Config {
private String driver;
private String url;
private String username;
private String password;
private int minConnections = 10;
private int maxConnections = 20;
private boolean autoCommitOnClose = true;
private int checkoutTimeout = 100;
private int checkTimes = 10;

public String getDriver() {
return driver;
}

public void setDriver(String driver) {
this.driver = driver;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getMinConnections() {
return minConnections;
}

public void setMinConnections(int minConnections) {
this.minConnections = minConnections;
}

public int getMaxConnections() {
return maxConnections;
}

public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}

public boolean isAutoCommitOnClose() {
return autoCommitOnClose;
}

public void setAutoCommitOnClose(boolean autoCommitOnClose) {
this.autoCommitOnClose = autoCommitOnClose;
}

public int getCheckoutTimeout() {
return checkoutTimeout;
}

public void setCheckoutTimeout(int checkoutTimeout) {
this.checkoutTimeout = checkoutTimeout;
}

public int getCheckTimes() {
return checkTimes;
}

public void setCheckTimes(int checkTimes) {
this.checkTimes = checkTimes;
}


}



PropertyReader.java

public class PropertyReader {
Logger log = Logger.getLogger(PropertyReader.class);
Properties props = null;
public PropertyReader(String path) throws IOException{
props = new Properties();
try {
props.load(getClass().getClassLoader().getResourceAsStream(path));
} catch (IOException e) {
log.error("读取properties失败");
throw e;
}
}
public String getValue(String key){
return props.getProperty(key);
}
}




DBPoolException .java

public class DBPoolException extends Throwable {
public DBPoolException(String str){
super(str);
}
}



properties配置文件

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
username=test
password=password
minConnections=10
maxConnections=30
#当链接关闭的时候自动将未提交的内容提交
autoCommitOnClose=false
#当连接池用完时客户端调用getConn()后等待获取新连接的时间,Default: (100毫秒)
checkoutTimeout=100
#当没有可用链接时,尝试获取链接的次数
checkTimes=30
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值