做网站时无法上传图片,wordpress注册中文插件,分销网站建设,一些简单的编程代码拓展阅读
第一节 从零开始手写 mybatis#xff08;一#xff09;MVP 版本。
第二节 从零开始手写 mybatis#xff08;二#xff09;mybatis interceptor 插件机制详解
第三节 从零开始手写 mybatis#xff08;三#xff09;jdbc pool 从零实现数据库连接池
第四节 从…拓展阅读
第一节 从零开始手写 mybatis一MVP 版本。
第二节 从零开始手写 mybatis二mybatis interceptor 插件机制详解
第三节 从零开始手写 mybatis三jdbc pool 从零实现数据库连接池
第四节 从零开始手写 mybatis四- mybatis 事务管理机制详解
连接池的作用
资源重用
由于数据库连接得到重用避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上 另一方面也增进了系统运行环境的平稳性减少内存碎片以及数据库临时进程/线程的数量。
更快的系统响应速度
数据库连接池在初始化过程中往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。 对于业务请求处理而言直接利用现有可用连接避免了数据库连接初始化和释放过程的时间开销从而缩减了系统整体响应时间。
新的资源分配手段
对于多应用共享同一数据库的系统而言可在应用层通过数据库连接的配置使用数据库连接池技术。 设置某一应用最大可用数据库连接数避免某一应用独占所有数据库资源。
统一的连接管理避免数据库连接泄漏
在较为完备的数据库连接池实现中可根据预先设定的连接占用超时时间强制收回被超时占用的连接。 从而避免了常规数据库连接操作中可能出现的资源泄漏当程序存在缺陷时申请的连接忘记关闭这时候就存在连接泄漏了。
中间件
常见实现对比
参考网上资料Druid TomcatJDBC DBCP C3P0BoneCP 的性能方面没有深入比较应该和 Tomcat Jdbc 差不多。
对于小型的系统并发压力不大时选择哪一种数据库连接池差别不会很大主要考虑的应该是连接池的稳定性。
当并发量较高时一般不会选择使用 DBCP 和C3P0选 Druid 是较好的。
手动实现
自己实现一个简化版便于理解原理。
连接池接口
public interface IPool {/*** 获取新的数据库链接* return 数据库链接*/PoolConnection getPoolConnection();
}
其中 PoolConnection 如下:
public class PoolConnection {/*** 是否繁忙*/private volatile boolean isBusy;/*** 数据库链接信息*/private Connection connection;
}
核心实现
public class PoolImpl implements IPool {/*** 数据库驱动*/private final String jdbcDriver;/*** 数据库连接*/private final String jdbcUrl;/*** 数据库用户名*/private final String username;/*** 数据库密码*/private final String passowrd;/*** 连接池大小*/private final int size;/*** 数据库连接池列表*/private ListPoolConnection poolConnections new ArrayList();public PoolImpl(String jdbcDriver, String jdbcUrl, String username, String passowrd, int size) {this.jdbcDriver jdbcDriver;this.jdbcUrl jdbcUrl;this.username username;this.passowrd passowrd;this.size size;init();}private void init() {try {//1. 注册数据库连接信息Driver sqlDriver (Driver) Class.forName(jdbcDriver).newInstance();DriverManager.registerDriver(sqlDriver);//2. 初始化连接池initConnectionPool();} catch (InstantiationException | IllegalAccessException | SQLException | ClassNotFoundException e) {e.printStackTrace();}}/*** 初始化链接* throws SQLException sql 异常*/private void initConnectionPool() throws SQLException {for(int i 0; i size; i) {Connection connection DriverManager.getConnection(jdbcUrl, username, passowrd);PoolConnection poolConnection new PoolConnection(false, connection);poolConnections.add(poolConnection);}}Overridepublic PoolConnection getPoolConnection() {if(poolConnections.size() 0) {return null;}PoolConnection poolConnection getRealConnection();while (poolConnection null) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}poolConnection getRealConnection();}return poolConnection;}/*** 获取数据库链接对象* return 数据库链接对象*/private synchronized PoolConnection getRealConnection() {for(PoolConnection poolConnection : poolConnections) {// 寻找不处于繁忙状态的连接if(!poolConnection.isBusy()) {Connection connection poolConnection.getConnection();// 测试当前连接是否有效try {if(!connection.isValid(5000)) {Connection validConnection DriverManager.getConnection(jdbcUrl, username, passowrd);poolConnection.setConnection(validConnection);}} catch (SQLException e) {e.printStackTrace();}// 设置为繁忙poolConnection.setBusy(true);return poolConnection;}}return null;}
}
线程池管理类
使用单例
public class PoolManager {/*** 连接池持有类*/private static class PoolHolder {private static String url ;private static String driver ;private static String username ;private static String password ;private static int size 10;private static IPool poolImpl new PoolImpl(driver, url, username, password, size);}/*** 内部类单利模式产生使用对象* return 单例*/public static IPool getInstance() {return PoolHolder.poolImpl;}
}