SpringBoot 底层如何去和 MySQL 交互了呢?
我们在写做 Java 项目时,一般都是引入 MyBatis 框架来和 MySQL 数据库交互,如果需要在 MySQL 上执行什么语句,只需要在 Mapper.xml 文件中定义对应的 SQL 语句即可
那么他底层到底是如何将定义在 Mapper.xml 文件中的 SQL 语句拿到 MySQL 中执行的呢?
其实 SpringBoot 项目底层就是通过和 MySQL 建立网络连接,之后通过这个连接来进行通信的
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
那么要建立和 MySQL 之间的连接,就要在项目中引入 MySQL 连接的 JDBC(Java Database Connectivity) 驱动,JDBC 就提供了 Java 程序和 MySQL 进行交互的接口
我们在 Java Web 刚入门的时候应该就学习了 JDBC,而在 MyBatis 中也是对 JDBC 进行了封装和抽象,提供了更丰富的功能给我们使用,先来看一下下边这张图,来详细说一下 SpringBoot 与 MySQL 如何进行交互:
用户发起一次 HTTP 请求的流程:
先从用户端说起,当用户对 SpringBoot 系统发起一个 HTTP 请求时,Tomcat 会创建一个线程来处理用户的请求,这个线程通过 JDBC 驱动来和数据库建立网络连接,将需要执行的 SQL 语句发送给 MySQL 数据库,MySQL 收到 SQL 之后执行语句,并将结果通过网络连接返回给 Tomcat 中的线程,最终再经过业务逻辑的处理,返回给用户
JDBC 驱动会为每一个线程都创建一个数据库连接吗?
上边说到了工作线程要和 MySQL 进行通信,就要建立一个数据库连接
那么假想一下如果对每一个线程都建立一个数据库连接,这里建立的连接是 TCP 连接,光建立连接就需要 3 次握手(3 次网络 IO),并且在使用完进行销毁,那么带来的性能开销是相当庞大的
基于这个问题,就引入了 数据库连接池,像我们常用的连接池就是 Druid 数据库连接池(阿里巴巴开源)
通过连接池,可以集中管理一批数据库连接,来供多个线程使用,使用完不销毁,再放回连接池可以进行复用,这样就省去了不断创建连接以及销毁连接的性能开销
在 Druid 连接池中维护了多个与 MySQL 的数据库连接,因此在 MySQL 中也是会有对应的连接池用于管理和外部的连接的,这里就省略不画了,只画了 Druid 中的连接池: