`
royzhou1985
  • 浏览: 253366 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

jdbc连接池简单封装

    博客分类:
  • Java
阅读更多
主要实现方法是:
使用一个容器(LinkedList),初始化的时候设定好连接数,生成Connection对象放在容器中
以后每次获取连接的时候都从容器中获取,但是这样有一个问题,当我们关闭连接的时候调用
Connection的close()方法的时候会直接将Connection关闭而不是重新放到容器中……
在这里使用的是代理,真正使用的是通过代理生成的一个存放在内存中的类,在这个类拦截了close()方法,在close()方法中将连接重新放回容器中......


数据库连接池类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyDataSource{
	
	private static String url = "jdbc:mysql://localhost:3306/jdbc";
	private static String user = "root";
	private static String password = "";
	
	//初始化连接个数
	private static int initCount = 1;
	
	//最大连接个数
	private static int maxCount = 1;
	
	//当前连接个数
	int currentCount = 0;

	/**
	 * 使用linkedList是由于频繁的对容器进行增加和删除操作,相比ArrayList快
	 */
	LinkedList<Connection> connectionsPool = new LinkedList<Connection>();
	
	/**
	 * 初始化数据连接池中的连接个数
	 * @throws ClassNotFoundException
	 */
	public MyDataSource() throws ClassNotFoundException {
		Class.forName("com.mysql.jdbc.Driver");
		try {
			for (int i = 0; i < initCount; i++) {
				this.connectionsPool.addLast(this.createConnection());
				this.currentCount++;
			}
		} catch (SQLException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	/**
	 * 从数据连接池中获取连接
	 * @return
	 * @throws SQLException
	 */
	public Connection getConnection() throws SQLException {
		synchronized (connectionsPool) {
			if (this.connectionsPool.size() > 0)
				return this.connectionsPool.removeFirst();

			if (this.currentCount < maxCount) {
				this.currentCount++;
				return this.createConnection();
			}

			throw new SQLException("��û��t��");
		}
	}
	
	/**
	 * 连接关闭后返回连接池中
	 * @param conn
	 */
	public void free(Connection conn) {
		this.connectionsPool.addLast(conn);
	}
	
	/**
	 * 创建连接,使用代理模式
	 * 实际上生成的不是java.sql.Connection
	 * proxy.bind(realConn);返回的是经过封装后的Connection
	 * 在其调用close()方法的时候拦截然后在close()方法中将连接放回连接池而不是直接关闭
	 * @return
	 * @throws SQLException
	 */
	private Connection createConnection() throws SQLException {
		Connection realConn = DriverManager.getConnection(url, user, password);
		MyConnectionHandler proxy = new MyConnectionHandler(this);
		return proxy.bind(realConn);
	}
	
	public static void main(String[] args) throws Exception {
		MyDataSource mds = new MyDataSource();
		for(int i=0; i<10; i++) {
			Connection conn = mds.getConnection();
			System.out.println(conn);
			conn.close();
		}
	}
}




代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

class MyConnectionHandler implements InvocationHandler {
	
	//普通的jdbc Connection
	private Connection realConnection;
	
	//通过代理在内存中生成的类
	private Connection warpedConnection;
	
	private MyDataSource dataSource;
	
	//每个连接最多使用次数
	private int maxUseCount = 5;
	
	//连接当前使用次数
	private int currentUserCount = 0;

	MyConnectionHandler(MyDataSource dataSource) {
		this.dataSource = dataSource;
	}

	/**
	 * 使用Proxy代理生成一个类
	 * 注意,生成的类不是我们以文本格式存在
	 * 而是存在内存中的
	 * @param realConn
	 * @return
	 */
	Connection bind(Connection realConn) {
		this.realConnection = realConn;
		/**
		 * Proxy.newProxyInstance(loader, interfaces, h)
		 * 其中loader是类加载器
		 * interfaces是要实现的接口,这里使用的是java.sql.Connection
		 * h是InvocationHandler,调用方法后交给哪个对象处理
		 */
		this.warpedConnection = (Connection) Proxy.newProxyInstance(this
				.getClass().getClassLoader(), new Class[] { Connection.class },
				this);
		return warpedConnection;
	}

	/**
	 * 每个代码实例都具有一个关联的调用处理程序。
	 * 对代理实例调用方法时,
	 * 将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//拦截close()方法,重写里面的方法
		if ("close".equals(method.getName())) {
			this.currentUserCount++;
			if (this.currentUserCount < this.maxUseCount)
				this.dataSource.connectionsPool.addLast(this.warpedConnection);
			else {
				this.realConnection.close();
				this.dataSource.currentCount--;
			}
		}
		//其他方法调用普通的jdbc Connection处理
		return method.invoke(this.realConnection, args);
	}

}



上述代码只是简单进行封装,主要是让大家了解一下数据库连接池的实现方式以及了解一下代理的实现,对以后学习Hibernate以及Spring的AOP有较大帮助
分享到:
评论
3 楼 pshaoyi 2015-03-18  
连接创建没问题,在执行的时候就报错了。

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:1115)
at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:3001)
at com.mysql.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:2996)
... 58 more
2 楼 alask2011 2012-02-24  
而且proxy.bind(realConn);好像返回的也不是代理对象,因为代理对象打印出来的时候都是 以 $ 开头的,这个还是普通的对象
1 楼 alask2011 2012-02-24  
封装的还是有问题,真正的连接超出使用次数的时候根本关不掉啊,
就是那个普通的jdbc连接关不掉,我close()之后还是可以打印的
this.realConnection.close();这一句

相关推荐

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

    JDBC(Java Database Connectivity)是Java与数据库交互的标准接口,而"jdbc连接池封装"则指的是对JDBC连接管理的优化。连接池是一种数据库资源复用机制,它可以预先创建并维护一定数量的数据库连接,当应用需要时...

    关于JDBC连接池的java类

    这个提供的"JDBC连接池"类很可能是一个封装好的数据源类,它简化了连接池的配置和使用过程,使得开发者可以更专注于业务逻辑。导入此类后,只需按照类库的API进行操作,就能方便地管理和使用数据库连接。 总的来说...

    游戏服务器 数据库连接池 jdbc 简单封装

    本文将深入探讨“游戏服务器数据库连接池JDBC简单封装”的相关知识点。 首先,我们需要理解JDBC(Java Database Connectivity)的概念。JDBC是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,提供了...

    jdbc连接池封装及ORM框架jdbc.rar

    在这个“jdbc连接池封装及ORM框架jdbc.rar”文件中,我们可以探讨几个核心概念和技术,包括设计模式的应用、注解的使用以及反射机制。 首先,**设计模式**在软件开发中起着至关重要的作用。例如,工厂模式可能被...

    jdbc连接池c3p0工具包

    **jdbc连接池c3p0工具包** 在Java开发中,数据库操作是常见的任务,而JDBC(Java Database Connectivity)是Java与数据库交互的标准接口。然而,直接使用JDBC进行数据库连接可能会导致性能问题,因为每次连接和断开...

    JDBC连接池&JDBCTemplate

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

    SQLite sql jdbc基于java的封装类

    关于java对SQLite和sql的封装类,可以实现增删改,查,事务操作

    JDBC小组件 对DBCP连接池的封装

    **JDBC小组件对DBCP连接池的封装详解** 在Java开发中,数据库操作是必不可少的一部分,而JDBC(Java Database Connectivity)则是Java与数据库交互的标准接口。然而,直接使用JDBC进行数据库操作存在效率低下、资源...

    HikariCP JDBC连接池 v5.1.0.zip

    《HikariCP JDBC连接池 v5.1.0:高效数据库连接管理的解析与实践》 HikariCP是一款高性能、轻量级的JDBC连接池,它以其卓越的性能和稳定性在Java社区中备受推崇。本次我们将深入探讨HikariCP v5.1.0版本中的关键...

    java JDBC 连接sql server封装

    以上就是一个基本的Java JDBC连接SQL Server的封装示例。通过这种方式,你可以轻松地在多个地方重用相同的连接逻辑,同时保持代码的整洁。记住,对于生产环境,最好使用连接池(如HikariCP、C3P0等)来管理和复用...

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

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

    spring声明式事务管理+jdbc+连接池.zip

    结合这三部分,Spring的声明式事务管理使得事务控制变得简单,JDBC提供了数据库操作的便利性,而连接池则优化了数据库连接的管理,提高了系统性能。在实际项目中,这些技术的综合运用能够帮助开发者更高效、更稳定地...

    JavaSE-jdbc连接池-每日作业卷答案1

    总结来说,Java SE JDBC连接池中的C3P0是一个强大的数据库连接池组件,提供了灵活的配置和高效的连接管理。通过使用C3P0,开发者可以提高应用程序的性能和资源利用率,同时简化数据库连接的管理。在实际项目中,结合...

    使用德鲁伊连接池封装JDBC

    使用德鲁伊连接池对JDBC进行简单封装的学习代码

    Oracle和c3p0连接池简单封装.

    C3P0则是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,提供了对JDBC连接的管理,使得数据库连接可以被多个请求共享,提高了系统的性能和效率。本文将详细介绍如何在Java开发中对Oracle数据库与C3P0连接池进行...

    jdbc 连接数据库封装类,可返回map,或者vo(自用)

    5. **NetJavaSession.java**:这个文件的名字可能暗示了它与网络会话有关,或者是对JDBC连接的进一步封装,提供了一种基于会话的数据库操作方式。可能包含事务管理、并发控制等特性,以确保数据的一致性和完整性。 ...

    day06_JDBC连接池&JDBCTemplate2

    JDBC(Java Database Connectivity)是...JDBC连接池和JDBCTemplate是其在实际开发中的两个重要补充,它们提高了性能和代码质量,简化了数据库操作的复杂度。了解并熟练掌握这些知识,对于Java开发人员来说至关重要。

    day06_JDBC连接池&JDBCTemplate_docx1

    【JDBC连接池&JDBCTemplate】是Java开发中处理数据库交互的重要技术。JDBC是Java Database Connectivity的缩写,它提供了一组接口和类,使得Java程序能够与各种类型的数据库进行通信。JDBC不仅是Java操作数据库的...

    jdbc连接数据库(jndi连接池)

    "jdbc连接数据库(jndi连接池)"这个主题涉及了几个关键的技术概念,包括Java Database Connectivity (JDBC),Java Naming and Directory Interface (JNDI)以及连接池技术。下面将详细阐述这些知识点。 1. JDBC:...

    JDBC数据库连接池相关jar包

    C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0的主要功能包括连接池管理、自动关闭空闲连接、异常处理等。通过C3P0,开发者可以在多个请求之间共享数据库连接,减少...

Global site tag (gtag.js) - Google Analytics