對比(5.1.48VS8.0.16)getConnection、isValid

一、驅動以及目錄結構

官網地址:https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/

1.1 驅動對比

5.1.48 引入驅動時名稱爲:com.mysql.jdbc.Driver

8.0.16 引入驅動時名稱爲:com.mysql.cj.jdbc.Driver ,如果 驅動還配置 5.x 的版本,也沒有問題,只是會如下提示:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

在這裏插入圖片描述
但是還是會自動 切換成 新的驅動,原因如下,主要是做了代碼兼容,讓原先的Driver繼承了com.mysql.cj.jdbc.Driver ,然後在
在這裏插入圖片描述
然後com.mysql.cj.jdbc.driver 裏面的 靜態塊 進行註冊:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    //
    // Register ourselves with the DriverManager
    //
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

在DriverManager 類裏面的 通過了SPI 進行了註冊和初始化:

/**
     * Load the initial JDBC drivers by checking the System property
     * jdbc.properties and then use the {@code ServiceLoader} mechanism
     */
    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }

在這裏插入圖片描述在這裏插入圖片描述

1.2 目錄結構對比

5.1.X的源碼目錄結構和 8.0.16 的代碼結構也有很大的變化,這裏就不貼圖了,感興趣的自己去下載源碼看,源碼地址:gitHub地址
這裏對比一下 對JDK 的要求:
在這裏插入圖片描述
此外,JDBC 版本和 JDK 對應的關係如下:

一、JDBC 1.0 隨JDK1.1發佈;
二、JDBC 2.0 隨JDK1.2 和 JDK1.3 發佈
JDBC 2.0 和 JDBC 2.1 API 被分入兩個包:
java.sql 包(包括核心 API;它是 JDBC 1.22 API 的增強)
javax.sql 包(可選的包,用於支持連接池、分佈式事務及其他類似的高級功能)。
三、JDBC3.0 隨JDK1.4發佈
四、JDBC 4.0 隨 JDK1.6 發佈
五、JDBC4.1 隨 JDK1.7 發佈
六、JDBC4.2 隨 JDK1.8 發佈

二 getConnection流程對比

這裏主要是分析的正常流程:

2.1 5.1.48版本getConnection

在這裏插入圖片描述
大致流程:

  1. 判斷url 是否爲空,爲空澤拋出異常
  2. 判斷url 是否以"jdbc:mysql:loadbalance://" 開頭,是則創建對應的負載均衡的connet,否則繼續步驟3
  3. 判斷url是否以“jdbc:mysql:replication://” 開頭,是澤創建對應的Replication
    的connect,否則繼續
  4. 對URL 進行 解析,轉換成Properties 以便後面使用
  5. 判斷NUM_HOSTS 是否 >1 ,是 則 走connectFailover 流程,否則繼續
  6. 判斷是否是 jdbc4, 是支持jdbc4的,那就先 通過構造函數實例JDBC4Connection
  7. JDBC4Connection 繼承了 ConnectionImpl,這裏 會 createNewIO(false); 進行和mysql server進行創建connection
  8. 通過StandardSocketFactory 創建 socketFactory,使用標準的 TCP/IP sockets (the
    standard) 進行socket 連接
  9. 通過BufferedOutputStream 進行 確定,這樣一個connection就創建完成.

2.2、8.0.16版本的getConnection流程

在這裏插入圖片描述
大致流程如下:

  1. 判斷url 是否爲空,如果爲空,拋出異常
  2. 通過正則表達式驗證 URL的開頭是否符合規定的,這裏 通過枚舉列出來,5.1.48 是逐個判斷,個人感覺8.0.X的 代碼結構相關整潔一些,類型如下,官方給出解釋,不同的數據庫用錯驅動比較常見,比如用的ServerSQL 的數據庫,用的mysql 的驅動在這裏插入圖片描述
  3. 對URL 進行拼接,拼接玩,用此鏈接作爲Key,從緩存裏面獲取對應的ConnectionUrl 實例
  private static final LRUCache<String, ConnectionUrl> connectionUrlCache = new LRUCache<>(100);

在這裏插入圖片描述
4. 獲取到了就直接返回,獲取不到就 通過 Class.forName 進行構造
5. 拿到ConnectionUrl 之後,根據對應的Type 進行和 mysql Server 創建Connection
6. 先對各類參數進行初始化,然後 createNewIO(false);
7. 這裏通過 TCP/IP sockets (the standard) 開始進行連接, 建立之後 ,連接的狀態是
:unauthenticated user,還沒去確認,等待client 端確認.
8. 這裏相對 5.1.48 做了進一步的細化, 創建了一個 protocol , 明確了:物理連接僅負責 I / O流,而 protocol 負責創建 session ,以及 內部認證,protocol 對 讀取和發送消息也進行了封裝.,這裏 protocol.connect 進行確認,正式創建連接

三、isValid 流程對比

兩個版本的isValid ,都是拿到連接之後,通過socket 發送一個 a ping command給到 mysql Server ,然後讀取對應的消息,如果獲取到的是 java.io.EOFException ,說明此connection 已經斷開,拋出異常, 兩個版本的大致流程基本一樣,這裏就不貼對比了,直接貼一下兩個的大致流程路徑:
在這裏插入圖片描述

四、對比總結

4.1 getConnection 小結

  1. 8.0.16 對整個代碼的結構進行了調整, 原先 5.1.x 很多的if …else 這類分支 ,8.0.16版本 通過正則 匹配 過濾掉不符合 規範的url ,再 通過 枚舉 方式 匹配對應的 情況,這樣代碼更加簡潔, 也更加直接,不符合的url 直接返回而不需要到創建的時候才發現不符合,效率更高.

  2. 8.0.16 裏面設置了一個 緩存,key 爲拼接好的URL ,value 對對應的connectionUrl, 創建連接時,每次的url一樣就不用每次都通過構造函數來進行創建 ,這裏進行了一定的優化,創建的速度更快

  3. 在 和mysql server 進行創建 連接時,都是創建socket 連接,但8.0.16 把很多的代碼進行了重新整合,引入了一個 protocol 輔助類,對一些讀寫 方法 都重新封裝,層次更加清晰了一些,也對校驗進行了一定程度的增強.

4.2 其他對比

  1. 8.0.16 依賴 JDBC 4.2 ,所以要求JDK1.8

  2. 8.0.16 版本修復了一些bug 和對一些方法進行了整合,詳見:mysql-connector-java 官方描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章