自己实现的一个简单的数据库连接池

自己突然就找到了以前学习的感觉,要不是完了这几个月英爱能找一份比现在好点的工作,说实话还是有点后悔,但是没关系,从现在开始加油还来得及。

今天首先学的是数据库连接,就想到了实现一个数据库连接池,虽然很Lower 但是还是记录下来,一步一个脚印.

首先实现方法是创建一个连接池对象,里面放一个List对象用来保存数据库连接,自己写一个类,实现Connection对象,在里面的close方法里面将连接还给连接池。

然后在从数据库连接池中获取数据的时候用removeFirst方法,移除并返回第一个对象,好的废话不多说上代码

package com.mysql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class JDBC_POOL {
	private static final String URL = "jdbc:mysql://localhost:3306/JDBC_TEST?useUnicode=true&characterEncoding=UTF-8";
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private static final String USER_NAME = "root";
	private static final String PASSWORD = "dbq228367/";
	/**
	 * 用来装连接池的容器
	 */
	public static LinkedList<myConnection> list = new LinkedList<myConnection>();

	/**
	 * 设置容器的大小
	 */
	public static int size = 100;

	static{
		 try{
			 for(int i=0;i<3;i++){
				 Connection conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
				 System.out.println("创建了数据库连接 : " + conn + " : " + conn.hashCode());
				 myConnection mc = new myConnection(conn);
				 list.add(mc);
			 }
		 }catch(Exception e){
			 System.out.println(e.getMessage());
			 e.printStackTrace();
		 }
	}

	public myConnection getConnection()throws Exception{
		if(list.size()==0 || list.size()<0){
			//连接池已经满了
			throw new Exception("连接池已经没有连接对象");
		}else{
			System.out.println("程序获取连接对象 : " + list.get(0).getConnection());
			return list.removeFirst();
		}
	}
}

  然后是实现Connection接口的自定义类

package com.mysql;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;

public class myConnection implements Connection{

	private Connection conn;

	public myConnection(Connection conn){
		this.conn = conn;
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		// TODO Auto-generated method stub
		return conn.unwrap(iface);
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		// TODO Auto-generated method stub
		return conn.isWrapperFor(iface);
	}

	@Override
	public Statement createStatement() throws SQLException {
		// TODO Auto-generated method stub
		return conn.createStatement();
	}

	@Override
	public PreparedStatement prepareStatement(String sql) throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement(sql);
	}

	@Override
	public CallableStatement prepareCall(String sql) throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareCall(sql);
	}

	@Override
	public String nativeSQL(String sql) throws SQLException {
		// TODO Auto-generated method stub
		return conn.nativeSQL(sql);
	}

	@Override
	public void setAutoCommit(boolean autoCommit) throws SQLException {
		// TODO Auto-generated method stub
		conn.setAutoCommit(autoCommit);
	}

	@Override
	public boolean getAutoCommit() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getAutoCommit();
	}

	@Override
	public void commit() throws SQLException {
		// TODO Auto-generated method stub
		conn.commit();
	}

	@Override
	public void rollback() throws SQLException {
		// TODO Auto-generated method stub
		conn.rollback();
	}

	@Override
	public void close() throws SQLException {
		// TODO Auto-generated method stub
		//在这里将连接对象还给连接池
		System.out.println("将连接对象还给连接池  : " + conn);
		JDBC_POOL.list.add(new myConnection(conn));
	}

	@Override
	public boolean isClosed() throws SQLException {
		// TODO Auto-generated method stub
		return conn.isClosed();
	}

	@Override
	public DatabaseMetaData getMetaData() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getMetaData();
	}

	@Override
	public void setReadOnly(boolean readOnly) throws SQLException {
		// TODO Auto-generated method stub
		conn.setReadOnly(readOnly);
	}

	@Override
	public boolean isReadOnly() throws SQLException {
		// TODO Auto-generated method stub
		return conn.isReadOnly();
	}

	@Override
	public void setCatalog(String catalog) throws SQLException {
		// TODO Auto-generated method stub
		conn.setCatalog(catalog);
	}

	@Override
	public String getCatalog() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getCatalog();
	}

	@Override
	public void setTransactionIsolation(int level) throws SQLException {
		// TODO Auto-generated method stub
		conn.setTransactionIsolation(level);
	}

	@Override
	public int getTransactionIsolation() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getTransactionIsolation();
	}

	@Override
	public SQLWarning getWarnings() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getWarnings();
	}

	@Override
	public void clearWarnings() throws SQLException {
		// TODO Auto-generated method stub
		conn.clearWarnings();
	}

	@Override
	public Statement createStatement(int resultSetType, int resultSetConcurrency)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.createStatement(resultSetType, resultSetConcurrency);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType,
			int resultSetConcurrency) throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement(sql, resultSetType,resultSetConcurrency);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType,
			int resultSetConcurrency) throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetConcurrency);
	}

	@Override
	public Map<String, Class<?>> getTypeMap() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getTypeMap();
	}

	@Override
	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
		// TODO Auto-generated method stub
		conn.setTypeMap(map);
	}

	@Override
	public void setHoldability(int holdability) throws SQLException {
		// TODO Auto-generated method stub
		conn.setHoldability(holdability);
	}

	@Override
	public int getHoldability() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getHoldability();
	}

	@Override
	public Savepoint setSavepoint() throws SQLException {
		// TODO Auto-generated method stub
		return conn.setSavepoint();
	}

	@Override
	public Savepoint setSavepoint(String name) throws SQLException {
		// TODO Auto-generated method stub
		return conn.setSavepoint(name);
	}

	@Override
	public void rollback(Savepoint savepoint) throws SQLException {
		// TODO Auto-generated method stub
		conn.rollback(savepoint);
	}

	@Override
	public void releaseSavepoint(Savepoint savepoint) throws SQLException {
		// TODO Auto-generated method stub
	    conn.releaseSavepoint(savepoint);
	}

	@Override
	public Statement createStatement(int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement(sql, resultSetType, resultSetConcurrency,resultSetHoldability);
	}

	@Override
	public CallableStatement prepareCall(String sql, int resultSetType,
			int resultSetConcurrency, int resultSetHoldability)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareCall( sql,  resultSetType,
				 resultSetConcurrency,  resultSetHoldability);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement( sql,  autoGeneratedKeys);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement( sql, columnIndexes);
	}

	@Override
	public PreparedStatement prepareStatement(String sql, String[] columnNames)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.prepareStatement( sql,  columnNames);
	}

	@Override
	public Clob createClob() throws SQLException {
		// TODO Auto-generated method stub
		return conn.createClob();
	}

	@Override
	public Blob createBlob() throws SQLException {
		// TODO Auto-generated method stub
		return conn.createBlob();
	}

	@Override
	public NClob createNClob() throws SQLException {
		// TODO Auto-generated method stub
		return conn.createNClob();
	}

	@Override
	public SQLXML createSQLXML() throws SQLException {
		// TODO Auto-generated method stub
		return conn.createSQLXML();
	}

	@Override
	public boolean isValid(int timeout) throws SQLException {
		// TODO Auto-generated method stub
		return conn.isValid(timeout);
	}

	@Override
	public void setClientInfo(String name, String value)
			throws SQLClientInfoException {
		// TODO Auto-generated method stub
		conn.setClientInfo(name, value);
	}

	@Override
	public void setClientInfo(Properties properties)
			throws SQLClientInfoException {
		// TODO Auto-generated method stub
		conn.setClientInfo(properties);
	}

	@Override
	public String getClientInfo(String name) throws SQLException {
		// TODO Auto-generated method stub
		return conn.getClientInfo(name);
	}

	@Override
	public Properties getClientInfo() throws SQLException {
		// TODO Auto-generated method stub
		return conn.getClientInfo();
	}

	@Override
	public Array createArrayOf(String typeName, Object[] elements)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.createArrayOf(typeName, elements);
	}

	@Override
	public Struct createStruct(String typeName, Object[] attributes)
			throws SQLException {
		// TODO Auto-generated method stub
		return conn.createStruct(typeName, attributes);
	}

	public Connection getConnection(){
		return this.conn;
	}
}

  注意看里面的close方法,和最后一个getConnection方法,getConnection方法是为了直观的观察数据库连接池里面对象的流转情况

然后在servlet里面调用并打印数据库连接池信息

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mysql.JDBC_POOL;
import com.mysql.myConnection;

public class getConnection extends HttpServlet {

	private static final long serialVersionUID = 1806541121588301641L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
         doPost(request,response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
          PrintWriter out = response.getWriter();
          try{
        	  Connection conn = new JDBC_POOL().getConnection();
        	  out.print(conn+" : " + conn.hashCode());
          }catch(Exception e){
        	  System.out.println(e.getMessage());
        	  e.printStackTrace();
          }finally{

          }
	}
}

  最后我们来看看效果

还有控制台打印的信息

创建了数据库连接 : [email protected] : 1720854532
创建了数据库连接 : [email protected] : 1192380230
创建了数据库连接 : [email protected] : 648734830
程序获取连接对象 : [email protected]

  再访问一次

创建了数据库连接 : [email protected] : 1720854532
创建了数据库连接 : [email protected] : 1192380230
创建了数据库连接 : [email protected] : 648734830
程序获取连接对象 : [email protected]
程序获取连接对象 : [email protected]

  第三次

创建了数据库连接 : [email protected] : 1720854532
创建了数据库连接 : [email protected] : 1192380230
创建了数据库连接 : [email protected] : 648734830
程序获取连接对象 : [email protected]
程序获取连接对象 : [email protected]
程序获取连接对象 : [email protected]

  好的这时候三个连接对象都取完了,我们来第四次访问

创建了数据库连接 : [email protected] : 1720854532
创建了数据库连接 : [email protected] : 1192380230
创建了数据库连接 : [email protected] : 648734830
程序获取连接对象 : [email protected]
程序获取连接对象 : [email protected]
程序获取连接对象 : [email protected]
连接池已经没有连接对象
java.lang.Exception: 连接池已经没有连接对象
	at com.mysql.JDBC_POOL.getConnection(JDBC_POOL.java:41)
	at com.servlet.getConnection.doPost(getConnection.java:26)
	at com.servlet.getConnection.doGet(getConnection.java:20)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)

  到这里和预想的一样,在servlet中如果释放了数据库连接,则我们也可以看到连接还给连接池的信息,这里就不再赘述。

时间: 2024-10-12 21:57:32

自己实现的一个简单的数据库连接池的相关文章

【java】简单实现数据库连接池

一直在想java事务是怎么实现的,在原声jdbc的时候级别下,我们可以通过关掉autocommit 然后再手动commit.但是项目开发中基本上是看不见conection的.所以自己决定简单实现框架的一点皮毛功能.首先就是数据库连接池了 1. 先定义一个接口 import java.sql.Connection; public interface IConnectionPool { /** * 获取一个连接 * @return */ Connection getConnection(); /**

一个简单的线程池程序设计(消费者和生产者)

最近在学习linux下的编程,刚开始接触感觉有点复杂,今天把线程里比较重要的线程池程序重新理解梳理一下. 实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任务队列不满,则把该任务加入到任务队列中去,并且向线程发送一个信号,调用某个线程为任务队列中的任务服务.如果线程池中的线程都在忙,那么任务队列中的任务则等待.本程序较为简单,把任务定义为了两个数相加,输出它们的和. 采用自顶向下的设计方法,先把整体框架构建出来,然后再慢慢把细节,小模块补全. 1.在l

Linux C 一个简单的线程池程序设计

实现功能:创建一个线程池,该线程池包含若干个线程,以及一个任务队列,当有新的任务出现时,如果任务队列不满,则把该任务加入到任务队列中去,并且向线程发送一个信号,调用某个线程为任务队列中的任务服务.如果线程池中的线程都在忙,那么任务队列中的任务则等待.本程序较为简单,把任务定义为了两个数相加,输出它们的和. 采用自顶向下的设计方法,先把整体框架构建出来,然后再慢慢把细节,小模块补全. 1.在linux环境下构建三个文件夹(include,src,bin) include:包含该程序所需要的头文件.

.Net——做一个简单代理IP池

一.缘由. 抓取数据时,有一些网站 设置了一些反爬虫设置,进而将自己本地 IP 地址拉入系统黑名单.从而达到禁止本地 IP 访问数据的请求. 二.思路. 根据其他 代理 IP 网站,进行一个免费的代理 IP 进行搜集,然后进行统一 验证 管理 如下图: 三.抓取包含代理 IP 的网站页面. 抓取来网站代码之后,利用 HtmlAgilityPack 进行 html 的解析.并将代理 IP 验证,存放队列等操作. 四.直接看效果图. 运行效果. 浏览器 请求 :http://127.0.0.1:12

简单的数据库连接池实例(java语言)

1.概述 频繁的创建和销毁数据库连接消耗非常多的系统资源,创建一个池子, 管理一定数量的连接,用的时候去池中取,用完了放回池中,这时比较通用的做法. 2.关键字 LinkedList  synchronized  InvocationHandler  CountDownLatch 3. 代码 3.1 ConnectionPool.java package com.rocky.pool; import java.sql.Connection; import java.util.LinkedList

Linux C 实现一个简单的线程池

线程池的定义 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程完成后才启动. 什么时

一个简单的线程池实现

前段时间学习了线程方面的知识,看了关于线程池的教程,自己也试着实现一个.跟大家分享,同时也整理整理思路.   对线程池的要求: 1.用于处理大量短暂的任务. 2.动态增加线程,直到达到最大允许的线程数量. 3.动态销毁线程.   线程池的实现类似于"消费者--生产者"模型: 用一个队列存放任务(仓库,缓存) 主线程添加任务(生产者生产任务) 新建线程函数执行任务(消费者执行任务) 由于任务队列是全部线程共享的,就涉及到同步问题.这里采用条件变量和互斥锁来实现. ------------

一个简单的线程池

/** * * @author hc * @version 1.0 * * @param <Job> */ public interface ThreadPool<Job extends Runnable>{ //执行一个job void execute(Job job); //关闭线程 void shutdown(); //增加工作者线程 void addWorkers(int num); //减少工作者线程 void removeWorkers(int num); //正在等待

JAVA写简单的数据库连接池

创建数据库连接以及关闭连接是很耗费时间的,并且数据库支持的连接数量也是有限的,当数据库的连接数量达到上限的时候,后续的连接就会失败.因此这里引入了数据库缓冲池. public class ConnecionPool { private int size; List<Connection> connections = new ArrayList<>(); public ConnecionPool(int size){ this.size=size; init(); } public