前段时间因为不小心删掉了这篇文章,经高人指点,决定再次粘上来。也由衷地感谢这位高人。企业项目中的数据库连接池都是已经写好,程序员直接拿来用就可以了。自己写一下算是了解一下底层的东西吧!写得不好的地方,希望大家多多指教!
public class DbConnectionManager {
private static DbConnectionManager dbConnectionManager= null;
private static int clientCount = 0;
private static Vector<Driver> drivers = new Vector<Driver>();//存放数据库驱动
//pools存放数据库连接池
private static Hashtable<String,DbConnectionPool> pools = new Hashtable<String,DbConnectionPool>();
private PrintWriter log = null;
private DbConnectionManager(){
init();
}
/**
* 〈得到DbConnectionManager实例<单例模式>〉
*/
public static synchronized DbConnectionManager getInstance(){
if(null == dbConnectionManager){
dbConnectionManager = new DbConnectionManager();
}
clientCount++;
return dbConnectionManager;
}
/**
* 〈获取连接〉
*/
public synchronized Connection getConnection(String name){
DbConnectionPool dbConnectionPool = pools.get(name);
Connection connection = null;
if(null != dbConnectionPool){
connection = dbConnectionPool.getConnection();
}
return connection;
}
/**
* 〈释放连接〉
*/
public void freeConnection(String name,Connection connection){
DbConnectionPool dbConnectionPool = pools.get(name);
if(null != dbConnectionPool){
dbConnectionPool.freeConnection(connection);
}
}
/**
* 〈加载数据库属性文件〉
*/
private void init(){
InputStream inputStream = this.getClass().getResourceAsStream("/db.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);
} catch (IOException e) {
System.err.println("Can't read the properties file. " + "Make sure db.properties is in the CLASSPATH");
return;
}
String logFile = properties.getProperty("logfile", "DBConnectionManager.log");
try {
log = new PrintWriter(new FileWriter(logFile, true), true);
} catch (IOException e) {
System.err.println("Can't open the log file: " + logFile);
log = new PrintWriter(System.err);
}
loadDrivers(properties);//加载驱动
createPool(properties);//创建数据库连接池
}
/**
* 〈创建连接池〉
*/
private void createPool(Properties properties) {
Enumeration propertyNames = properties.propertyNames();
String propertyName = null;
while(propertyNames.hasMoreElements()){
propertyName = (String) propertyNames.nextElement();
if(propertyName.endsWith("url")){
String poolName = propertyName.substring(0, propertyName.lastIndexOf("."));
String url = properties.getProperty(propertyName);
String userName = properties.getProperty(poolName+".userName");
String password = properties.getProperty(poolName+".password");
String maxConn = properties.getProperty(poolName+".maxConn");
int max = 0;
try{
max = Integer.parseInt(maxConn);
}catch(NumberFormatException e){
max = 0;
}
DbConnectionPool dbConnectionPool = new DbConnectionPool(
poolName,url,userName,password,max);
pools.put(poolName, dbConnectionPool);
}
}
}
/**
* 〈释放连接池〉
*/
public void freePools(){
if(0 == --clientCount){
Enumeration<DbConnectionPool> allPools = pools.elements();
DbConnectionPool dbConnectionPool = null;
while(allPools.hasMoreElements()){
dbConnectionPool = allPools.nextElement();
dbConnectionPool.freeConnections();
}
Enumeration<Driver> allDrivers = drivers.elements();
while (allDrivers.hasMoreElements()) {
Driver driver = (Driver) allDrivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
}
}
}
}
/**
* 〈加载驱动〉
*/
private void loadDrivers(Properties properties){
String driverClass = properties.getProperty("drivers");
Driver driver = null;
try {
driver = (Driver) Class.forName(driverClass).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
drivers.addElement(driver);
}
private class DbConnectionPool{
private String poolName;
private String url;
private String userName;
private String password;
private int maxConn;
private final Vector<Connection> freeConnections = new Vector<Connection>();
private int checkedOut;
public DbConnectionPool(String poolName,String url,String userName,String password,int maxConn){
this.poolName = poolName;
this.url = url;
this.userName = userName;
this.password = password;
this.maxConn = maxConn;
}
/**
* 〈获取连接〉
*/
public Connection getConnection() {
Connection connection = null;
if(freeConnections.size()>0){
connection = freeConnections.firstElement();
freeConnections.remove(0);
try {
if (connection.isClosed()) {
connection = getConnection();
}
} catch (SQLException e) {
connection = getConnection();
}
}else if((0 == maxConn)|| checkedOut < maxConn){
connection = newConnection();
}
if(null != connection){
checkedOut++;
}
return connection;
}
/**
* 〈释放单个连接〉
*/
public void freeConnection(Connection connection) {
freeConnections.addElement(connection);
checkedOut--;
notifyAll();
}
/**
* 〈创建连接〉
*/
public Connection newConnection() {
Connection connection = null;
try {
if(null == userName){
DriverManager.getConnection(url);
}else {
connection = DriverManager.getConnection(url, userName, password);
}
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/**
* 〈释放所有连接〉
*/
public void freeConnections() {
Enumeration<Connection> connections = freeConnections.elements();
Connection connection = null;
while(connections.hasMoreElements()){
connection = connections.nextElement();
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
freeConnections.removeAllElements();
}
}
}
分享到:
相关推荐
【项目介绍】基于C++11和Linux环境的自写数据库连接池源码+项目说明.zip关键技术要点- MySQL数据库编程- 设计模式中的单例模式- STL中的queue队列容器- C++11多线程编程- C++11线程互斥、线程同步通信和unique_lock-...
在给定的标题“自己写的数据库连接池(java)”中,我们可以推测这是一个用户自定义的数据库连接池实现,可能是为了学习或实践目的。描述提到的“XML版读取属性文件”和“普通的”,暗示了两种不同的配置方式,一种是...
基于C++11和Linux环境的自写数据库连接池项目源码+文档说明.zip 【说明】 【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 ...
数据库连接池是Java应用程序中非常重要的一个组件,它在提高应用性能、节省系统资源方面起着关键作用。本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及...
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。 在较为完备的数据库连接池实现中,可根据...
数据库连接池是数据库管理中的重要概念,特别是在高并发和大数据量的应用场景下,它能显著提升性能并降低系统资源消耗。在C#编程环境中,我们可以使用自定义的数据库连接池来实现这一功能。本篇文章将深入探讨“C#...
数据库连接池是数据库管理中的一个重要概念,它在C#编程中扮演着优化数据库操作的关键角色。C#数据库连接池是一种管理数据库连接的技术,通过复用已存在的连接而不是每次请求时都创建新的连接,从而提高数据库操作的...
数据库连接池是Java开发中非常重要的一个概念,它在处理大量并发访问数据库的应用场景中扮演着关键角色。本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池...
数据库连接池是应用程序管理数据库连接的一种机制,它在多个并发请求之间共享数据库连接,从而减少了创建和销毁数据库连接的开销。在这个项目中,你使用Java实现了一个自定义的数据库连接池,应用了代理模式来优化...
数据库连接池是现代应用程序开发中的重要组成部分,尤其是在处理大量数据交互的应用中,它极大地提高了数据库操作的效率和系统的稳定性。本资源"03-数据库连接池驱动"包含了三种常用的数据库连接池驱动:C3P0、Druid...
本文将深入探讨如何在C#中使用MySQL数据库连接池。 首先,我们需要了解什么是数据库连接池。数据库连接池是一种资源管理技术,它预先创建并维护一定数量的数据库连接,当应用需要时,可以从池中获取连接,使用完毕...
Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...
本资源集合了常用的JDBC数据库连接jar包,以及一些知名的数据库连接池实现,如dbcp和c3p0,这对于开发人员来说是非常宝贵的资源。 首先,让我们了解一下JDBC。JDBC提供了一套标准的API,包括接口和类,使得开发者...
* 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...
context.xml, 数据库连接池配置文
数据库连接池是数据库管理系统中的一个重要概念,主要用于优化数据库的连接操作。在C#编程中,数据库连接池可以高效地管理数据库连接,避免频繁创建和销毁连接导致的性能开销。本文将详细介绍C#中数据库连接池的工作...
数据库连接池是现代应用程序中管理数据库连接的一种高效方式,它能显著提高系统性能,减少资源消耗。在给定的标题“配置数据库连接池”中,我们可以深入探讨数据库连接池的概念、工作原理,以及如何配置Oracle9i和...