DBMNG数据库管理与应用

所谓独创的能力,就是经过深思的模仿。
当前位置:首页 > 经验分享 > Java组件

JDBC数据库连接池的简单实现

以前写的一段程序,试图按着自己对多线程与JDBC的理解,实现数据库链接池的功能。运行时也还正常,就是感觉程序太简单。现在看起来也的确太简单,好多复杂的情形都没有考虑到。

 

包结构:
org.eleaf.java.eshop.db/
|---db.properties
|---Database.java
|---ConnectionPool.java

db.properties:配置文件

##--------------
# MySql
#--------------
#db.driver=com.mysql.jdbc.Driver
#db.username=bitan
#db.password=abcd
#db.url=jdbc:mysql://localhost/eshop?useUnicode=true&characterEncoding=GBK
#db.maxConnections=10
#--------------
# Sql Server
#--------------
db.driver=com.jnetdirect.jsql.JSQLDriver
db.username=sa
db.password=
db.url=jdbc:JSQLConnect://server/database=xxxx
db.maxConnections=10
#--------------
# Oracle
#--------------
#db.driver=oracle.jdbc.driver.OracleDriver
#db.username=xxx
#db.password=xxx
#db.url=jdbc:oracle:thin:@SERVER:1521:ORACLEDB
#db.maxConnections=10

 

 

Database.java:从配置文件读取信息,创建数据库连接

/*
* Created on 2005-2-19
*
*/
package org.eleaf.java.eshop.db;

import java.sql.*;
import java.io.*;
import org.eleaf.java.eshop.mvc.util.*;


public class Database {
private static Database instance;
private final String propFile="db.properties";
private final String driver;
private final String url;
private final String username;
private final String password;
private final int maxConnections;
public static Database getInstance() throws SQLException{
if (instance == null) {
instance = new Database();
}
return instance;
}
private Database() throws SQLException{
try {
PropertiesParser parser = new PropertiesParser(propFile, this);
driver = parser.getValue("db.driver");
url = parser.getValue("db.url");
username = parser.getValue("db.username");
password = parser.getValue("db.password");
String strMaxConns = parser.getValue("db.maxConnections");
maxConnections = Integer.parseInt(strMaxConns);
} catch (IOException e) {
throw new SQLException("IOException: " + e.getMessage());
}
}

/**
* @return Returns the driver.
*/
public String getDriver() {
return driver;
}
/**
* @return Returns the password.
*/
public String getPassword() {
return password;
}
/**
* @return Returns the url.
*/
public String getUrl() {
return url;
}
/**
* @return Returns the username.
*/
public String getUsername() {
return username;
}

/**
* @return Returns the maxConnections.
*/
public int getMaxConnections() {
return maxConnections;
}
/**
* @return Returns the propFile.
*/
public String getPropFile() {
return propFile;
}
Connection getConnection() throws SQLException{
Connection conn = null;
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
throw new SQLException(e.getMessage());
}
return conn;
}
}



ConnectionPool.java:数据库连接池

/*
* Created on 2005-3-24
*
*/
package org.eleaf.java.eshop.db;

import java.sql.*;
import java.util.*;


public class ConnectionPool {
<!--StartFragment -->private final int MAX_CONNS; //最大连接数 
private Vector freeConns; 
//当前可用空闲连接集合
private int activeConns; //当前活动连接 
private Database db; //包含JDBC驱动、URL、用户名、密码等基本信息并生成数据库连接的一个 类。
<!--StartFragment -->private static ConnectionPool instance;
//单例模式 
public static synchronized ConnectionPool getInstance() throws SQLException {
if (instance == null ) {
instance = new ConnectionPool();
}
return instance;
}
public ConnectionPool() throws SQLException {
db = Database.getInstance();
freeConns = new Vector();
MAX_CONNS = db.getMaxConnections(); 
activeConns = 0;
showInfo("ConnectionPool()");
}
<!--StartFragment -->
 //创建新连接
private Connection createNewConnection() throws SQLException {
showInfo("createNewConnection()");
return db.getConnection();
}
<!--StartFragment -->
 //从连接池中取得连接
public synchronized Connection getConnection() throws SQLException {
while (activeConns >= MAX_CONNS) {<!--StartFragment --> //如果活动连接数超过了最大允许数,则等待1秒钟。 
try {
wait(1000); 
catch (InterruptedException e) {
e.printStackTrace();
}
}
Connection conn = null;
if (freeConns.size() <= 0) {<!--StartFragment --> //如果当前可用空闲连接为0,则创建新连接 
conn = createNewConnection();
activeConns++;
else {
conn = (Connection) freeConns.get(0); <!--StartFragment --> //如果当前可用空闲连接不为0,则从池中取出第一个空闲连接。 
freeConns.remove(0);
if (conn == null ) {
System.out.println("_______________");
conn = createNewConnection();
}
activeConns++;
}
showInfo("getConnection()");
return conn;
}
<!--StartFragment -->//线程程序执行完毕,要主动返回连接到连接池中。 
public synchronized void returnConnection(Connection conn) throws SQLException {
if (conn == null || conn.isClosed()) {
return;
}
if (activeConns > MAX_CONNS) {
conn.close();
conn = null ;
 
else {
freeConns.addElement(conn);
}
activeConns--;
showInfo("returnConnection(Connection)");
notify();<!--StartFragment --> //连接返回到池中后,通告其它等待取得连接的线程。 
}
private void showInfo(String str) {
String t = Thread.currentThread().getName();
String tmp = t + " : " + str + " : activeConns=" + activeConns +
", freeConns=" + freeConns.size(); 
System.out.println(tmp);
}
<!--StartFragment -->
 //一段测试程序
public static void main(String[] args) {
System.out.println("*************");
final ConnectionPool cp = ConnectionPool.getInstance();
Thread[] ths = new Thread[100]; 
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(
new Runnable() {
public void run() {
Connection conn = cp.getConnection();
try {
cp.showInfo("start business...");
Thread.sleep(500);
cp.showInfo("end business...");
catch (InterruptedException e) {
e.printStackTrace();
}
cp.returnConnection(conn);
}
}, "T" + (i + 1)
);
}
for (int i = 0; i < ths.length; i++) {
ths[i].start();
}
}
}


测试结果:略

本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号