连接池

作者: Dl_毛良伟 | 来源:发表于2017-05-04 11:51 被阅读80次

- 自定义连接池

普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。连接池可以避免这些问题
实现步骤:

  1. 指定全局参数 : 初始化数目 最大连接数 当前连接 连接池集合
  2. 在构造函数中 : 循环创建三个连接
  3. 实现一个创建连接的方法
  4. 获取连接
  5. 关闭连接

代码部分:

package com.demo01.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

/**
 * Created by pc on 17-5-1.
 */
public class MyPool {
    private int init_count = 3;  //初始化链接数目
    private int max_count = 6;   //最大连接数目
    private int current_count;   //记录连接数
    //连接池,存放所有初始化连接
    private LinkedList<Connection> pool = new LinkedList<Connection>();

    //1.构造函数中将初始化连接放入连接池中
    public MyPool() {
        //初始化连接
        for (int i = 0; i < init_count; i++) {
            //记录当前连接条数
            current_count++;
            //把连接放入连接池中
            pool.addLast(createConnection());
        }
    }

    //2.创建一个新的连接对象
    public Connection createConnection() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //3.获取连接
    public Connection getConnection() {
        //判断连接池是否有连接,如果有则直接取出
        if (pool.size() > 0) {
            return pool.removeFirst();
        }
        //如果连接池的连接以取完,判断是否超过最大连接数,如果没有则创建
        if (current_count < max_count) {
            current_count++;
            return createConnection();
        }
        //如果超过最大连接数,则抛出异常
        throw new RuntimeException("超过最大连接数");
    }

    //4.释放链接
    public void realeaseConnection(Connection connection) throws SQLException {
        //如果连接池没有放满连接,则将该链接放回连接池
        if (current_count < pool.size()) {
            pool.addLast(connection);
            current_count--;
        } else {
            connection.close();
            current_count--;
        }
    }

}

- DBCP连接池

DBCP(DataBase connection pool)数据库连接池是 apache 上的一个Java连接池项目。DBCP通过连接池预先同数据库建立一些连接放在内存中(即连接池中),应用程序需要建立数据库连接时直接到从接池中申请一个连接使用,用完后由连接池回收该连接,从而达到连接复用,减少资源消耗的目的。
引入jar文件,使用maven配置这两个文件:

  • commons-dbcp2
  • commons-pool2
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.0.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.2</version>
        </dependency>


代码部分

package com.demo01.test;

import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * Created by pc on 17-5-1.
 */
public class Test_dbcp {

    @Test
    public void testDbcp() throws SQLException {
        //DBCP连接池核心
        BasicDataSource dataSource = new BasicDataSource();

        //连接池参数配置:初始化连接数,最大连接数  /连接字符串,驱动,用户,密码
        dataSource.setUrl("jdbc:mysql:///jdbcdemo?useUnicode=true&characterEncoding=utf-8");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setInitialSize(3);
        dataSource.setMaxIdle(3000);
        //dataSource.setMaxTotal(6);
        //获取连接
        Connection conn = dataSource.getConnection();
        conn.prepareStatement("delete FROM admin where id=9").executeUpdate();

        //关闭连接
        conn.close();
    }

}

image.png

- c3p0连接池

c3p0与dbcp区别
dbcp没有自动回收空闲连接的功能
c3p0有自动回收空闲连接功能
demo

package demo01.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.sql.Connection;

public class demo {

    @Test
    //1. 硬编码方式,使用C3P0连接池管理连接
    public void testCode() throws Exception {
        // 创建连接池核心工具类
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 设置连接参数:url、驱动、用户密码、初始连接数、最大连接数
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcdemo");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        dataSource.setInitialPoolSize(3);
        dataSource.setMaxPoolSize(6);
        dataSource.setMaxIdleTime(1000);

        // ---> 从连接池对象中,获取连接对象
        Connection con = dataSource.getConnection();
        // 执行更新
        con.prepareStatement("delete from admin where id=7").executeUpdate();
        // 关闭
        con.close();
    }

    @Test
    //2. XML配置方式,使用C3P0连接池管理连接
    public void testXML() throws Exception {
        // 创建c3p0连接池核心工具类
        ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置

        // 获取连接
        Connection con = dataSource.getConnection();
        // 执行更新
        con.prepareStatement("delete from admin where id=5").executeUpdate();
        // 关闭
        con.close();

    }
}

原始数据表
操作后的数据表

相关文章

  • 撩课-JavaWeb之什么是连接池与连接池使用

    什么是连接池 没有连接池的情况 数据库连接池 池 连接池 作用 数据库连接池 示意图 连接池中的属性 连接池使用 ...

  • 代码分析

    interface 相关配置 默认子连接池 定义全局连接池 注册连接池 默认子连接池 连接

  • JDBC 进阶——连接池

    本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...

  • SSM框架mybatis深入了解(二)

    一、mybatis中的连接池及事务控制 1.mybatis中的连接池使用及分析 1.1 连接池简介连接池是创建和...

  • JDBC进阶学习笔记

    JDBC进阶 JDBC连接池 1. 常见的JDBC连接池 c3p0 开源连接池 druid 阿里的开源数据库连接池...

  • Druid连接池

    第一章 连接池 一.1. 遇到的问题-引出连接池 | | 一.2. 连接池思想 | | 一.3. 连接池的概述 一...

  • JAEE学习笔记(19)事物与连接池

    目录 1.事务2.连接池 1.连接池概念 2.自定义连接池 3.开源连接池(c3p0) 复习: =========...

  • Redis连接池的使用

    1 . 安装 2 . 注册 redis 连接池 使用连接池

  • DBUtiles的使用

    自定义连接池: 学会用resourcebundle来加载properties文件 运用连接池的技术 连接池技术原理...

  • 连接池原理

    什么是连接池 上游对下游发起的请求,比如数据库连接池crud操作 为什么使用连接池? 如果不使用连接池,每次请求到...

网友评论

  • 6d96978eeefb:异常处理不太好,当出现连不上的时候,你是打印的错误日志,并且返回了一个null,放到了池子里,但是后面又没有对这个null进行任何的判断,就直接使用了。

    你需要思考一下,这里的异常我们应该怎么处理最好?
    6d96978eeefb: @Dl_毛良伟 另外学习一个东西都是有一个目标的,就是你为什么要学这个东西,你期望学到什么程度,能解决什么问题,只要到达了目标就可以停止了,而不是漫无目的的一直往前钻,这样反而是非常低效的学习
    6d96978eeefb: @Dl_毛良伟 当你觉得再继续往下学很艰难的时候,就可以停下来了,当然要把发现的问题留个记号,等到以后知识更全面的时候,再继续解决
    Dl_毛良伟: @TW李鹏 嗯,谢谢老师的细心点评,就我现在而言,我还不能确定我应该怎么去学一个新知识,应不应该去深入的学习,还是知道他的用法就行了,在以后再去慢慢填充这些不足?
  • 6d96978eeefb:Class.forName("com.mysql.jdbc.Driver");

    这行代码只需要调用一次,还是每一次都需要调用?
  • 6d96978eeefb:另外你的代码不是线程安全的,可以说明一下
  • 6d96978eeefb:return createConnection();

    你这里新生成的连接不用放到池子里了吗?

本文标题:连接池

本文链接:https://www.haomeiwen.com/subject/wgxqtxtx.html