首先自己实现一个简单的连接池:

数据准备:

CREATE DATABASE mybase;
USE mybase;
CREATE TABLE users(
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(64),
upassword VARCHAR(64)
);
INSERT INTO users (username,upassword) VALUES("zhangsan","123"),("lisi","456"),("wangwu","789");
SELECT * FROM users;

提取JDBC工具类:

package demo;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties; public class JDBCUtils3 {
public static String driver;
public static String url;
public static String username;
public static String password; static {
try {
ClassLoader classLoader = JDBCUtils3.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("db.properties");
Properties props = new Properties();
props.load(is);
driver = props.getProperty("driver");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
} catch (Exception ex) {
ex.printStackTrace();
}
} public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception ex) {
ex.printStackTrace();
}
return conn;
} public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
} }
}

配置文件db.properties:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybase
username=root
password=xuyiqing

自定义连接池:

package demo1;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger; import javax.sql.DataSource; import demo.JDBCUtils3; public class MyDataSource implements DataSource{
//1.创建1个容器用于存储Connection对象
private static LinkedList<Connection> pool = new LinkedList<Connection>(); //2.创建5个连接放到容器中去
static{
for (int i = 0; i < 5; i++) {
Connection conn = JDBCUtils3.getConnection();
pool.add(conn);
}
} /**
* 重写获取连接的方法
*/
@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
//3.使用前先判断
if(pool.size()==0){
//4.池子里面没有,我们再创建一些
for (int i = 0; i < 5; i++) {
conn = JDBCUtils3.getConnection();
pool.add(conn);
}
}
//5.从池子里面获取一个连接对象Connection
conn = pool.remove(0);
return conn;
} /**
* 归还连接对象到连接池中去
*/
public void backConnection(Connection conn){
pool.add(conn);
} @Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub } @Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
} @Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
} @Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
} }

测试:

package demo1;

import java.sql.Connection;
import java.sql.PreparedStatement; import org.junit.Test; public class TestMyDataSource {
@Test
public void testAddUser() {
Connection conn = null;
PreparedStatement pstmt = null;
// 1.创建自定义连接池对象
MyDataSource dataSource = new MyDataSource();
try {
// 2.从池子中获取连接
conn = dataSource.getConnection();
String sql = "insert into users values(null,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "吕布");
pstmt.setString(2, "貂蝉");
int rows = pstmt.executeUpdate();
if (rows > 0) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
dataSource.backConnection(conn);
}
}
}

测试:输出:添加成功!

接下来要做到放回连接的时候,调用了close方法却不是关闭资源,而是放回到池中

这时候需要一个自定义类实现Connection接口

package demo1;

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.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor; //1.实现同一个接口Connection
public class MyConnection implements Connection {
//3.定义一个变量
private Connection conn; private LinkedList<Connection> pool; // 2.编写一个构造方法(参数使用了面相对象的多态特性)
public MyConnection(Connection conn,LinkedList<Connection> pool) {
this.conn=conn;
this.pool=pool;
} //4.书写需要增强的方法
@Override
public void close() throws SQLException {
pool.add(conn);
} /**
* 此方法必须覆盖!否则会出现空指针异常!!!
*/
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return conn.prepareStatement(sql);
} @Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public Statement createStatement() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public CallableStatement prepareCall(String sql) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public String nativeSQL(String sql) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
// TODO Auto-generated method stub } @Override
public boolean getAutoCommit() throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public void commit() throws SQLException {
// TODO Auto-generated method stub } @Override
public void rollback() throws SQLException {
// TODO Auto-generated method stub } @Override
public boolean isClosed() throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public DatabaseMetaData getMetaData() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setReadOnly(boolean readOnly) throws SQLException {
// TODO Auto-generated method stub } @Override
public boolean isReadOnly() throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public void setCatalog(String catalog) throws SQLException {
// TODO Auto-generated method stub } @Override
public String getCatalog() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setTransactionIsolation(int level) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getTransactionIsolation() throws SQLException {
// TODO Auto-generated method stub
return 0;
} @Override
public SQLWarning getWarnings() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void clearWarnings() throws SQLException {
// TODO Auto-generated method stub } @Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
// TODO Auto-generated method stub } @Override
public void setHoldability(int holdability) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getHoldability() throws SQLException {
// TODO Auto-generated method stub
return 0;
} @Override
public Savepoint setSavepoint() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Savepoint setSavepoint(String name) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void rollback(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub } @Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub } @Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Clob createClob() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Blob createBlob() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public NClob createNClob() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public SQLXML createSQLXML() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public boolean isValid(int timeout) throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
// TODO Auto-generated method stub } @Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
// TODO Auto-generated method stub } @Override
public String getClientInfo(String name) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Properties getClientInfo() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setSchema(String schema) throws SQLException {
// TODO Auto-generated method stub } @Override
public String getSchema() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void abort(Executor executor) throws SQLException {
// TODO Auto-generated method stub } @Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getNetworkTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
} }

修改自定义连接池类:

package demo1;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger; import javax.sql.DataSource; import demo.JDBCUtils3; public class MyDataSource implements DataSource {
// 1.创建1个容器用于存储Connection对象
private static LinkedList<Connection> pool = new LinkedList<Connection>(); // 2.创建5个连接放到容器中去
static {
for (int i = 0; i < 5; i++) {
Connection conn = JDBCUtils3.getConnection();
// 放入池子中connection对象已经经过改造了
MyConnection myconn = new MyConnection(conn, pool);
pool.add(myconn);
}
} /**
* 重写获取连接的方法
*/
@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
// 3.使用前先判断
if (pool.size() == 0) {
// 4.池子里面没有,我们再创建一些
for (int i = 0; i < 5; i++) {
conn = JDBCUtils3.getConnection();
// 放入池子中connection对象已经经过改造了
MyConnection myconn = new MyConnection(conn, pool);
pool.add(myconn);
}
}
// 5.从池子里面获取一个连接对象Connection
conn = pool.remove(0);
return conn;
} /**
* 归还连接对象到连接池中去
*/
public void backConnection(Connection conn) {
pool.add(conn);
} @Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub } @Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub } @Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
} @Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
} @Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
} @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
} @Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
} }

测试:

package demo1;

import java.sql.Connection;
import java.sql.PreparedStatement; import javax.sql.DataSource; import org.junit.Test; import demo.JDBCUtils3; public class TestMyDataSource {
@Test
public void testAddUser1() {
Connection conn = null;
PreparedStatement pstmt = null;
// 1.创建自定义连接池对象
DataSource dataSource = new MyDataSource();
try {
// 2.从池子中获取连接
conn = dataSource.getConnection();
String sql = "insert into users values(null,?,?)";
//3.必须在自定义的connection类中重写prepareStatement(sql)方法
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "吕布1");
pstmt.setString(2, "貂蝉1");
int rows = pstmt.executeUpdate();
if (rows > 0) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtils3.release(conn, pstmt, null);
}
}
}

添加成功!

JDBC连接池原理、自定义连接池代码实现的更多相关文章

  1. Executors提供的四种线程池和自定义线程池

    JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...

  2. JDBC连接池一 自定义连接池

    package com.mozq.jdbc; import java.io.IOException; import java.io.InputStream; import java.sql.Conne ...

  3. JDBC自定义连接池

    开发中,"获得连接"和"释放资源"是非常消耗系统资源的,为了解决此类性能问题可以采用连接池技术来共享连接Connection. 1.概述 用池来管理Connec ...

  4. SpringBoot 自定义线程池

    本教程目录: 自定义线程池 配置spring默认的线程池 1. 自定义线程池 1.1 修改application.properties task.pool.corePoolSize=20 task.p ...

  5. EntityFramework Core上下文实例池原理分析

    前言 无论是在我个人博客还是著作中,对于上下文实例池都只是通过大量文字描述来讲解其基本原理,而且也是浅尝辄止,导致我们对其认识仍是一知半解,本文我们摆源码,从源头开始分析.希望通过本文从源码的分析,我 ...

  6. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  7. SpringBoot 自定义线程池,多线程

    原文:https://www.jianshu.com/p/832f2b162450 我们都知道spring只是为我们简单的处理线程池,每次用到线程总会new 一个新的线程,效率不高,所以我们需要自定义 ...

  8. JDBC数据源连接池(4)---自定义数据源连接池

    [续上文<JDBC数据源连接池(3)---Tomcat集成DBCP>] 我们已经 了解了DBCP,C3P0,以及Tomcat内置的数据源连接池,那么,这些数据源连接池是如何实现的呢?为了究 ...

  9. JDBC连接池-自定义连接池

    JDBC连接池 java JDBC连接中用到Connection   在每次对数据进行增删查改 都要 开启  .关闭  ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例 pack ...

随机推荐

  1. TCP与UDP,可靠UDP如何实现

    两种协议都是传输层协议,为应用层提供信息载体. TCP协议是基于连接的字节流的可靠协议,有三次握手,四次挥手,超时重传,流量控制(滑动窗口),拥塞控制和差错控制,也正因为有可靠性的保证和控制手段,所以 ...

  2. Java6及以上版本对synchronized的优化

    目录 1.概述 2.实现同步的基础 3.实现方式 4.Java对象头(存储锁类型) 5.优化后synchronized锁的分类 6.锁的升级(进化) 6-1.偏向锁 6-2.轻量级锁 6-3.锁的比较 ...

  3. linux目录与文件权限的意义

    现在我们已经知道了Linux系统内文件的三种身份(所有者,用户者,与其他人),知道每种身份都有三种属性(r,w,x),已经能够使用chown,chgrp,chmod去修改这些权限和属性,那么这些文件权 ...

  4. 关于EXCEPT和INTERSECT的用法和例子

    EXCEPT是指在第一个集合中存在,但是不存在于第二个集合中的数据. INTERSECT是指在两个集合中都存在的数据. select qq from #table1 如下: select qq fro ...

  5. MFC---关于string.h相关函数

    1.在VS2005中使用strcpy.strcat.sprintf出现如:mfc中'strcpy' was declared deprecated警告 这是因为VS2005中认为CRT中的一组函数如果 ...

  6. python获取文件夹的大小(即取出所有文件计算大小)

    import os path = r'/Users/authurchen/PycharmProjects/Demo' # print(os.listdir(path)) ls = os.listdir ...

  7. Redis 高级特性

    Redis 数据结构 Redis 常用的数据类型主要有以下五种: String Hash List Set Sorted set Redis 内部使用一个 redisObject 对象来表示所有的 k ...

  8. AltiumDesigner PCB导入CAD

    点击File菜单下的New的PCB,新建PCB文件. 在AD09中点击File菜单下的Import,导入CAD文件 选择要导入的CAD文件,点击打开. 选择单位mm,这里的单位选择要与CAD单位一致, ...

  9. EF多字段求和(分组/不分组)

    分组多字段求和 query.GroupBy(q => new { q.Year, q.Month }) .Select(q => new { Year = q.Key.Year, Mont ...

  10. nodejs 箭头函数

    背景 箭头函数,出现于ES6规范中. 使用 就是lambda函数. 一般使用: (a, b) => { return a + b; } 简略模式: 当参数只有一个时,可以省略括号:当返回值只有一 ...