`
coolxing
  • 浏览: 874821 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
9a45b66b-c585-3a35-8680-2e466b75e3f8
Java Concurre...
浏览量:97532
社区版块
存档分类
最新评论

自定义JDBC连接池及常用连接池介绍

    博客分类:
  • JDBC
阅读更多

[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.]

 

如果不采用连接池技术, 将导致不断创建和销毁数据库Connection, 造成性能上的损耗. 而数据库连接池技术将在池中创建一定数量的Connection, 当需要Connection时就从池中取出一个, 用完之后归还给连接池, 而不是将其销毁.

自定义数据库连接池的具体步骤分析:

a. 定义MyDataSource类, 实现DataSource接口, 并提供接口中定义的方法. 其中, 核心方法为Connection getConnection().

b. 可以在静态代码块或构造函数中创建多个Connection对象, 并将他们存储在LinkedList中. 当调用MyDataSource对象的getConnection()方法时, 从集合中取出一个Connection返回给调用者. 当调用者使用完Connection并调用Connection对象的close()方法时, 将该Connection对象归还给连接池.

c. 调用Connection对象的close()方法时, 为阻止系统销毁该连接, 而改为将连接归还给连接池, 可以采用包装设计模式. 此时包装的目标类为Connection, 因此需要定义MyConnection类并实现Connection接口. MyConnection类应该存在2个成员: Connection对象和LinkedList<Connection>对象, 这2个成员可以通过构造函数存入. 同时需要覆写close()方法, 在close()方法中实现将Connection添加到集合中.

代码如下:

 

public class MyDataSource implements DataSource {
	// 存储Connection对象的集合, 该集合最好采用LinkedList实现, 因为涉及到大量的删除和添加操作.
	private List<Connection> conns = new LinkedList<Connection>();

	public MyDataSource(String propertiesFileName) throws IOException,
			ClassNotFoundException, SQLException {
		// 连接池中Connection对象的数量
		int initialSize = 10;
		// 根据配置文件的名称获得InputStream对象
		InputStream in = MyDataSource.class.getClassLoader()
				.getResourceAsStream(propertiesFileName);
		// 使用Properties读取配置文件
		Properties prop = new Properties();
		prop.load(in);
		String url = prop.getProperty("url");
		String user = prop.getProperty("user");
		String password = prop.getProperty("password");
		String driver = prop.getProperty("driver");

		// 加载数据库驱动
		Class.forName(driver);
		// 根据配置文件中的信息获取数据库连接
		for (int i = 0; i < initialSize; i++) {
			Connection conn = DriverManager.getConnection(url, user, password);
			conns.add(conn);
		}
	}

	@Override
	public Connection getConnection() throws SQLException {
		// 获取从集合中移除的Connection对象, 并将其包装为MyConnection对象后返回.
		Connection conn = conns.remove(0);
		// 测试代码
		System.out.println("获取连接之后, 连接池中的Connection对象的数量为: " + conns.size());
		return new MyConnection(conn, conns);
	}

	private class MyConnection implements Connection {
		private Connection conn;
		private List<Connection> conns;

		public MyConnection(Connection conn, List<Connection> conns) {
			this.conn = conn;
			this.conns = conns;
		}

		// 重写close()方法, 实现调用该方法时将连接归还给连接池
		@Override
		public void close() throws SQLException {
			conns.add(conn);
			// 测试代码
			System.out.println("将连接归还给连接池后, 连接池中的Connection对象的数量为: " + conns.size());
		}

		// 对于其他方法, 直接调用conn对象的相应方法即可
		@Override
		public void clearWarnings() throws SQLException {
			conn.clearWarnings();
		}

		@Override
		public void commit() throws SQLException {
			conn.commit();
		}

		// 省略了其余Connection接口中定义的方法...

	}

	// 省略了其他DataSource接口中定义的方法...
}

以下是测试代码:

// create table person(id int primary key auto_increment, name varchar(40), age int);
public class JDBCPool {
	@Test
	public void myDataSourceTest() {
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		try {
			MyDataSource pool = new MyDataSource("db.properties");
			conn = pool.getConnection();
			String sql = "insert into person(name, age) values('min', 22)";
			st = conn.prepareStatement(sql);
			st.executeUpdate();

			sql = "select * from person";
			st = conn.prepareStatement(sql);
			rs = st.executeQuery();
			if (rs.next()) {
				System.out.println("id = " + rs.getInt("id") + ", name = "
						+ rs.getString("name") + ", age = " + rs.getInt("age"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 在release方法内会调用conn对象的close()方法
			release(null, st, conn);
		}
	}

	// 释放资源
	public void release(ResultSet rs, Statement st, Connection conn) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
			rs = null;
		} finally {
			try {
				if (st != null) {
					st.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
				st = null;
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}
				} catch (SQLException e) {
					e.printStackTrace();
					conn = null;
				}
			}
		}
	}
}

 

程序的输出为:

 

获取连接之后, 连接池中的Connection对象的数量为: 9

id = 6, name = min, age = 22

id = 7, name = coolxing, age = 24

将连接归还给连接池后, 连接池中的Connection对象的数量为: 10

可见这个自定义的连接池是可以工作的.

 

自定义数据库连接池只是为了学习JDBC连接池的原理, 平时项目使用的时候, 还是应该以开源的数据库连接池为主. 

常用的数据库连接池为DBCP, C3P0, 以及TOMCAT内置的连接池. 下面简单的介绍以下前两者的使用.

 

1. DBCP连接池使用步骤:

a. 导入Commons-dbcp.jar和Commons-pool.jar到project中.

b. 获取数据源DataSource对象. 可以直接创建BasicDataSource对象后调用相应的set方法, 如:

DataSource pool = new BasicDataSource();

pool.setUrl("jdbc:mysql://localhost:3306/exercise");

pool.setUsername("root");

pool.setPassword("root");

pool.setDriverClassName("com.mysql.jdbc.Driver");

pool.setInitialSize(10);

也可以通过工厂类加载配置文件获得DataSource对象, 如:

Properties prop = new Properties();

InputStream in = JDBCPool.class.getClassLoader().getResourceAsStream("dbcp.properties");

prop.load(in);

DataSource pool = BasicDataSourceFactory.createDataSource(prop);

c. 调用DataSource对象的getConnection()方法获得连接.

 

2. C3P0连接池的使用步骤:

a. 导入c3p0-0.9.1.2.jar和c3p0-0.9.1.2-jdk1.3.jar.

b. 获取数据源DataSource对象. 可以直接创建ComboPooledDataSource对象后调用相应的set方法, 如:

ComboPooledDataSource pool = new ComboPooledDataSource();

pool.setJdbcUrl("jdbc:mysql://localhost:3306/exercise");

pool.setUser("root");

pool.setPassword("root");

pool.setDriverClass("com.mysql.jdbc.Driver");

pool.setInitialPoolSize(10);

也可以在创建ComboPooledDataSource对象时传入配置节点的名称, 此时需要存在c3p0-config.xml文件. 如:

// 创建连接池, 并从c3p0-config.xml文件中的name属性为mysql的named-config元素中读取参数

ComboPooledDataSource pool = new ComboPooledDataSource("mysql");

c. 调用DataSource对象的getConnection()方法获得连接.

 

 

5
6
分享到:
评论

相关推荐

    自定义高并发jdbc连接池

    "自定义高并发jdbc连接池"是一个专为处理大量并发请求而设计的解决方案,它允许应用程序高效地管理和复用数据库连接,从而减少数据库连接创建与释放的开销,提高系统的整体性能。 JDBC(Java Database Connectivity...

    java JDBC连接池

    Java JDBC连接池是一种高效管理数据库连接的技术,它允许应用程序重复使用已经建立的数据库连接,从而减少频繁创建和关闭连接带来的开销。在大型系统中,尤其是高并发环境下,使用连接池能够显著提升性能并降低资源...

    简单的jdbc连接池类

    本示例中的"简单的jdbc连接池类"实现了一个基本的数据库连接池功能,非常适合初学者理解和实践。 首先,我们来理解`jdbc`。JDBC(Java Database Connectivity)是Java语言用来与各种数据库进行交互的一种标准接口。...

    jdbc连接池

    总的来说,这个压缩包提供的内容可能是一个自定义的JDBC连接池实现,结合了`jdom.jar`库进行配置,并提供了一个测试示例。学习和理解这个实现可以帮助开发者更好地掌握数据库连接池的工作原理,以及如何在实际项目中...

    自定义的数据库连接池

    9. **事务管理**:在JDBC中,事务通常在连接上进行管理,连接池需要考虑如何与事务管理配合,尤其是在多线程环境下。 10. **缓存预热和预加载**:启动时预先建立一部分连接,以减少首次请求时的延迟。 自定义...

    HikariCP JDBC连接池 v3.4.5.zip

    HikariCP是一款高效、高性能的Java JDBC连接池,它被设计为替代传统连接池如C3P0和DBCP,以提供更快、更稳定的数据访问性能。在HikariCP v3.4.5这个版本中,我们可以深入探讨其在数据库连接管理、性能优化以及配置...

    自定义一个简单的JDBC连接池实现方法

    自定义一个简单的JDBC连接池实现方法 知识点一:什么是JDBC连接池? JDBC连接池是一种优化数据库连接的方法,在传统的JDBC连接中,每次获得一个Connection连接都需要加载通过一些繁杂的代码去获取,这样繁杂的...

    JDBC连接池&DBUtils1

    JDBC 连接池 & DBUtils JDBC 连接池是 Java 中的一种机制,用于提高数据库连接的效率。传统的 JDBC 操作中,需要频繁地创建和销毁连接,这会消耗大量的时间和资源。使用连接池可以解决这个问题,连接池可以在程序...

    JDBC连接池&JDBCTemplate

    **JDBC连接池&JDBCTemplate** 在Java Web开发中,JDBC(Java Database Connectivity)是用于连接Java应用程序和数据库的标准接口。然而,直接使用JDBC进行数据库操作存在一些效率问题,比如频繁创建和关闭数据库...

    jdbc连接池技术代码

    下面将详细介绍JDBC连接池的工作原理、常见实现以及如何通过代码实现连接池管理器。 1. **JDBC连接池工作原理**: - 初始化:在应用程序启动时,连接池会预加载一定数量的数据库连接。 - 请求连接:当程序需要与...

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

    总结来说,JDBC数据库连接池如Druid的实现主要涉及以下几个步骤:引入依赖、配置连接池属性、在代码中使用连接池以及可选的监控和扩展。通过这些方式,我们可以有效地管理和优化数据库连接,提高应用的运行效率。

    自定义连接池案例

    自己写的连接池如果想知道连接池是怎么实现的就动手下载吧!

    HikariCP JDBC连接池 v4.0.3.zip

    《HikariCP JDBC连接池 v4.0.3:高效数据库连接管理的揭秘》 在现代Web应用程序中,数据库连接管理是至关重要的一个环节,它直接影响到系统的性能和稳定性。HikariCP,作为一款知名的JDBC连接池,以其高效、轻量级...

    javaBean自动生成工具,jdbc连接池封装

    在描述中提到的"JDBCUtils"很可能是一个自定义的Java类,封装了JDBC连接池的初始化、获取连接、释放连接等操作。这个工具类通常会集成已有的连接池实现,如C3P0、DBCP、HikariCP或Druid等,通过简单的API调用即可...

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

    本示例将详细介绍如何使用简单的JDBC实现一个数据库连接池。首先,我们来理解数据库连接池的基本概念。 数据库连接池是一种在应用服务器启动时预先创建并管理一定数量的数据库连接的机制。应用程序在需要时可以从...

    数据库连接池案例包括c3p0,druid,和自己手写的连接池

    首先,C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0的主要特性包括连接测试、自动关闭空闲连接、连接池扩展以及并发性能优化等。使用C3P0时,开发者需要配置相关的...

    JDBC自定义连接池过程详解

    二、JDBC连接池技术 Java为数据库连接池提供了公共接口:javax.sql.DataSource。各个厂商需要让自己的连接池实现这个接口。常见的连接池包括DBCP、C3P02、自定义连接池等。 三、自定义连接池 自定义连接池是指...

Global site tag (gtag.js) - Google Analytics