当前位置:   article > 正文

HikariCP:HikariCP连接池的简述及入门_hikari和hikaricp

hikari和hikaricp

池化思想概述

​ 池化思想是我们项目开发过程中的一种非常重要的思想,如整数池,字符串池,对象池、 连接池、线程池等都是池化思想的一种应用,都是通过复用对象,以减少因创建和释放对象 所带来的资源消耗,进而来提升系统性能。

说明:

​ 因为如果不采用池化思想,每次需要使用该对象,就需要创建一个该对象,当然如果不使用该对象了,就需要调用GC。GC在销毁该对象时,需要调用CPU,此时会占用一些资源。如果使用池化思想,创建过的对象就放到池中,下次需要使用时,复用该对象就可以了,一定程度上减少了资源的占用

Integer整数池案例:

public class IntegerTests{
    public static void main(String[] args) {
        //演示整数池(-128~+127)
        Integer n1=100;//Integer.valueOf(100)
        Integer n2=100;
        //对整数而言为什么不将所有整数都放到池中,而只是存储了一部分数据呢?
        //池设计的目的是?以空间换时间,这块空间中应该存储一些常用的整数数据
        Integer n3=200;//new Integer(200)
        Integer n4=200;
        System.out.println(n1==n2);//true
        System.out.println(n3==n4);//false
        //所有池的设计都会用到一种设计模式:享元模式 (通过池复用对象)
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

数据库连接池

​ 项目开发过程中应用程序与数据库交互时,“获得连接”或“释放连接”是非常消耗系 统资源的两个过程,频繁地进行数据库连接的建立和关闭会极大影响系统的性能,若多线程 并发量很大,这样耗时的数据库连接就可能让系统变得卡顿。因为 TCP 连接的创建开支十 分昂贵,并且数据库所能承载的 TCP 并发连接数也有限制,针对这种场景,数据库连接池应运而生。(数据库连接池复用的对象是“连接”)

图示:

在这里插入图片描述

对“频繁地进行数据库连接的建立和关闭会极大影响系统的性能”的理解:

​ 进行数据库连接的”建立“与"关闭"的操作需要基于TCP协议去实现,因此每次的”建立“与"关闭"都需要三次握手及四次挥手,对cpu资源的占用比较大,如果频繁的进行数据库交互,并发量变大,系统就会出现卡顿等情况,一定程度上影响了系统的性能。

​ Java 官方,为了在应用程序中更好的应用连接池技术,定义了一套数据源规范,例如 javax.sql.DataSource 接口,基于这个接口,很多团队或个人创建了不同的连接池对象。

​ 然后我们的应用程序中通过耦合与 DataSource 接口,便可以方便的切换不同厂商的连接池。Java 项目中通过连接池获取连接的一个基本过程,如图所示:

在这里插入图片描述

​ 用户通过 DataSource 对象的 getConnection()方法,获取一个连接。

​ 假如池中有连接,则直接将连接返回给用户。

​ 假如池中没有连接,则会调用 Dirver(驱动, 由数据库厂商进行实现)对象的 connect 方法从数据库获取,拿到连接以后,可以将连接在池中放一份,然后将连接返回给调用方。

​ 连接需求方再次需要连接时,可以从池中获取, 用完以后再还给池对象。

拓展1-数据库连接池的江湖

​ 数据库连接池在 Java 数据库相关中间件产品群中,应该算是底层最基础的一类产品, 作为企业应用开发必不可少的组件,无数天才们为我们贡献了一个又一个的优秀产品,它们有的随时代发展,功成身退,有的则还在不断迭代,老而弥坚,更有新生代产品,或性能无 敌,或功能全面。目前市场上常见的连接池有 DBCP、C3P0,DRUID,HikariCP 等。

拓展2-数据库连接池的原理分析

​ 在系统初始化的时候,在内存中开辟一片空间,将一定数量的数据库连接作为对象存储 在对象池里,并对外提供数据库连接的获取和归还方法。

​ 用户访问数据库时,并不是建立一 个新的连接,而是从数据库连接池中取出一个已有的空闲连接对象;使用完毕归还后的连接 也不会马上关闭,而是由数据库连接池统一管理回收,为下一次借用做好准备。

​ 如果由于高并发请求导致数据库连接池中的连接被借用完毕,其他线程就会等待,直到有连接被归还。 整个过程中,连接并不会关闭,而是源源不断地循环使用,有借有还。

​ 数据库连接池还可以 通过设置其参数来控制连接池中的初始连接数、连接的上下限数,以及每个连接的最大使用 次数、最大空闲时间等,也可以通过其自身的管理机制来监视数据库连接的数量、使用情况 等。

拓展3-数据库连接池的构成分析

​ 数据库连接池以连接池的管理为核心,主要支持连接池的建立和释放这两大核心功能。

​ “麻雀虽小,五脏俱全”,数据库连接池还可以支持其他非常实用的功能。一款商用的数据库 连接池、一款能够被开发者广泛使用的数据库连接池、一款能够在开源社区持续活跃发展的 数据库连接池还必须再支持一些实用的功能,如并发(锁性能优化乃至无锁)、连接数控制 (不同的系统对连接数有不同的需求)、监控(一些自身管理机制来监视连接的数量及使用 情况等)、外部配置(各种主流数据库连接池官方文档最核心的部分)、资源重用(数据库连 接池的核心思想)、检测及容灾(面对一些网络、时间等问题的自愈)、多库多服务(如不同 的数据库、不同的用户名和密码、分库分表等情况)、事务处理(对数据库的操作符合 ALLALL-NOTHING 原则)、定时任务(如空闲检查、最小连接数控制)、缓存(如 PSCache 等避 免对 SQL 重复解析)、异常处理(对 JDBC 访问的异常统一处理)、组件维护(如连接状态、 JDBC 封装的维护)等。

DataSource接口

案例:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 通过此单元测试类获取数据源对象,并且通过数据对象获取数据库连接
 * @SpringBootTest 注解描述的类
 * 为springboot中的单元测试类
 * 说明:
 * 1)springboot中的单元测试类必须放在启动类所在包-
 * -或子包中
 * 2)springboot中的单元测试类必须使用@SpringBootTest注解描述
 */
@SpringBootTest
public class DataSourceTests {

    /**
     * 在项目中添加了数据库相关依赖以后,springboot底层会自动帮我们配置一个
     * 数据源(DataSource)对象,此对象是连接池的规范.
     * @Autowired注解描述属性时,是告诉spring框架,要基于反射机制为属性赋值(依赖注入)
     * 赋值时,首先会基于属性类型从spring容器查找相匹配的对象, 假如只有一个则直接注入,
     * 有多个相同类型的对象时,还会比较属性名(检测属性名是否与bean名字相同),有相同的
     * 则直接注入(没有相同的直接抛出异常.)
     */
    @Autowired
    private DataSource dataSource;

    @Test   //org.junit.jupiter.api.Test
    void getConnections() throws SQLException {
        //获取链接时,会基于dataSource获取连接池对象,进而从池中获取连接
        Connection conn = dataSource.getConnection();
        System.out.println(conn);
        //结果:HikariProxyConnection@773518491 wrapping com.mysql.cj.jdbc.ConnectionImpl@3fd2322d
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

快速入门实战

添加依赖

		<!--链接 mysql 时使用的 mysql 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--当添加 data-jdbc 依赖时会自动下载 HikariCp 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

配置数据库信息

#application.pepoerties文件
#Spring DataSource 配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_notice?serverTimezone=GMT%2B8&charsetEnconding=utf8;
spring.datasource.username=root
spring.datasource.password=123456
  • 1
  • 2
  • 3
  • 4
  • 5

编写单元测试类

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

@SpringBootTest
public class JdbcTests {
    @Autowired
    private DataSource dataSource;

    @Test
    void testInsert() throws SQLException {

        //JDBC (是java中推出的连接数据库的一组API,是规范)
        //数据库厂商提供JDBC驱动(jdbc规范的实现)负责实现数据库的操作.
        //1.建立连接 (负责与数据库进行通讯)
        Connection conn = dataSource.getConnection();
        //2.创建statement(sql传送器->负责与将sql发送到数据库端)
        Statement stat = conn.createStatement();
        //准备sql语句
        String sql="insert into sys_notice " +
                " (title,content,type,status,createdTime,createdUser,modifiedTime,modifiedUser) " +
                "  values ('加课通知','本周六加课','1','0',now(),'xiaj',now(),'xiaj') ";
        //3.发送sql
        stat.execute(sql);
        //4.处理结果
        //5.释放资源(后续释放资源要写到finally代码块中)
        stat.close();
        conn.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

API运行原理分析

在这里插入图片描述

以上,仅供学习参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/160723
推荐阅读
相关标签
  

闽ICP备14008679号