数据库连接池的原理(与传统连接机制的对比)、作用与使用步骤

目录

一、传统的连接机制与数据库连接池的运行机制区别

写在前面:为什么在连接数据库时要使用连接池

1、不使用连接池流程

2、使用连接池流程

2.1连接池的作用

2.1数据库连接池的工作原理

2.3 常见连接池介绍

 二、 连接池(Druid)的使用

1、使用步骤

1.1 定义配置文件 druid.properties

1.2 编程实例

1.3 自定义 jdbc工具类


一、传统的连接机制与数据库连接池的运行机制区别

写在前面:为什么在连接数据库时要使用连接池

数据库连接是一种关键的有限的昂贵的资源,一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的 性能低下。 连接池技术尽可能多地重用了消耗内存地资源,大大节省了内存,提高了服务器地服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。 

1、不使用连接池流程

下面以访问MySQL为例,执行一个SQL命令,如果不使用连接池,需要经过哪些流程。

数据库连接池的原理(与传统连接机制的对比)、作用与使用步骤_第1张图片

不使用数据库连接池的步骤: 

  1. TCP建立连接的三次握手
  2. MySQL认证的三次握手
  3. 真正的SQL执行
  4. MySQL的关闭
  5. TCP的四次握手关闭

传统连接机制的缺点:

  1. 网络IO较多
  2. 数据库的负载较高
  3. 响应时间较长及QPS较低
  4. 应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁
  5. 在关闭连接后,会出现大量TIME_WAIT 的TCP状态(在2个MSL之后关闭)

2、使用连接池流程

数据库连接池的原理(与传统连接机制的对比)、作用与使用步骤_第2张图片

2.1连接池的作用

连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建连接和销毁连接的过程。这样性能上得到了提高。

2.1数据库连接池的工作原理

 第一、连接池的建立。一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。

第二、连接池的管理。连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:1)当客户请求数据库连接时,首先查看连接池中是否有空闲连接如果存在空闲连接,则将连接分配给客户使用;如果没有空闲连接,则查看当前所开的连接数是否已经达到最大连接数,如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的最大等待时间进行等待,如果超出最大等待时间,则抛出异常给客户。2)当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。(该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销)

第三、连接池的关闭。当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。

2.3 常见连接池介绍

 数据库连接池:
        1、Druid:阿里巴巴提供的技术支持
        2、C3p0:数据库连接池技术(hibernate 底层使用)
        3、dbcp:数据库连接池

 二、 连接池(Druid)的使用

1、使用步骤

    步骤:
            1、导入jar包 druid的jar
            2、定义配置文件
                xxx.properties
            3、加载配置文件
            4、获取数据库连接池对象
            5、获取数据库连接

1.1 定义配置文件 druid.properties

driverClassName=com.mysql.jdbc.Driver   //固定语句

//数据库地址   jdbc:mysql ://ip地址:端口号/数据库名
url=jdbc:mysql:///homework
	
username=root
password=1

//初始化连接的数量
initialSize=5

//最大连接的数量  设为0表示无限制
maxActive=10

//允许等待的最初时间 ,单位 毫秒
maxWait=3000

1.2 编程实例

 //获取配置文件
        Properties properties = new Properties();
        InputStream in = TestServlet.class.getClassLoader().getResourceAsStream("druid.properties");
        properties.load(in);


            //获取连接池对象
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

            //获取连接
            Connection connection = dataSource.getConnection();

				//sql语句
            String sql = "select*from student";
            //获取预编译执行者
            PreparedStatement ps = connection.prepareStatement(sql);
            //获取结果集
            ResultSet resultSet = ps.executeQuery();

1.3 自定义 jdbc工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {

    private static DataSource dataSource;
    static{
        //获取配置文件数据

        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties properties = new Properties();
            properties.load(in);
            //获取连接池对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        }  catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接
     * @return 数据库连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     * 获取数据库连接池
     * @return
     */
    public static DataSource getDataSource(){
        return dataSource;
    }

    /**
     * 释放资源
     * @param statement 语句执行者
     * @param conn 数据库连接对象
     */
    public static void close(Statement statement,Connection conn){
        try {
            statement.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Statement statement, Connection conn, ResultSet resultSet){
        try {
            if(statement != null){
                statement.close();
            }
            if(conn != null){
                conn.close();
            }
            if(resultSet != null){
                resultSet.close();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

关于其他两种连接池的使用:请阅读博文: https://www.cnblogs.com/sharpest/p/6240475.html

你可能感兴趣的:(面试系列,MySQL,数据库连接池的作用,数据库连接池的原理,druid的使用步骤,传统连接机制的原理)