欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決JDBC的class.forName()問題

 更新時間:2022年09月27日 09:23:30   作者:藍黑2020  
這篇文章主要介紹了關(guān)于JDBC的class.forName()問題,比較兩個Java文件可見,連接Db2和連接MySQL的方式非常類似,唯一的區(qū)別在于,調(diào)用?DriverManager.getConnection()?方法時,傳入的URL不同,本文給大家詳細講解,需要的朋友參考下

環(huán)境

  • Ubuntu 22.04
  • IntelliJ IDEA 2022.1.3
  • JDK 17.0.3
  • Db2 v11.5.0.0
  • MySQL Ver 8.0.30

準備

Db2

在Db2的 sample 數(shù)據(jù)庫中,創(chuàng)建表 t1 ,并插入一些數(shù)據(jù)。如下:

?  ~ db2 "select * from t1"

C1          C2          C3         
----------- ----------- -----------
          1         444           -
          2         222           -
          3         333           -

  3 record(s) selected.

MySQL

在MySQL的 repo 數(shù)據(jù)庫中,創(chuàng)建表 t1 ,并插入一些數(shù)據(jù)。如下:

mysql> select * from t1;
+------+-------+
| c1   | c2    |
+------+-------+
|    1 |  9800 |
|    2 | 10200 |
+------+-------+
2 rows in set (0.00 sec)

代碼

創(chuàng)建Maven項目 test0924 。

修改 pom.xml 文件,添加依賴:

......
        <!-- https://mvnrepository.com/artifact/com.ibm.db2/jcc -->
        <dependency>
            <groupId>com.ibm.db2</groupId>
            <artifactId>jcc</artifactId>
            <version>11.5.7.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
......

如上,在項目添加了Db2和MySQL的JDBC驅(qū)動。

Db2

創(chuàng)建類 Test0924_Db2

package pkg1;

import java.sql.*;

public class Test0924_Db2 {
    public static void main(String[] args) throws ClassNotFoundException {
//        Class.forName("com.ibm.db2.jcc.DB2Driver");
        try (
                Connection connection = DriverManager.getConnection("jdbc:db2://localhost:50000/sample",
                        "db2inst1", "passw0rd");

                Statement stmt = connection.createStatement();

                ResultSet rs = stmt.executeQuery("select * from t1");
        ) {
//            System.out.println(connection.getClass().getName());

            while (rs.next()) {
                System.out.println(rs.getInt(1));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

運行程序,結(jié)果如下:

1
2
3

MySQL

創(chuàng)建類 Test0924_Mysql

package pkg1;

import java.sql.*;

public class Test0924_Mysql {
    public static void main(String[] args) throws ClassNotFoundException {
//        Class.forName("com.mysql.jdbc.Driver");
        try (
                Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/repo",
                        "root", "123456");

                Statement stmt = connection.createStatement();

                ResultSet rs = stmt.executeQuery("select * from t1");
        ) {
//            System.out.println(connection.getClass().getName());

            while (rs.next()) {
                System.out.println(rs.getInt(1));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

運行程序,結(jié)果如下:

1
2

分析

JDBC

比較兩個Java文件可見,連接Db2和連接MySQL的方式非常類似,唯一的區(qū)別在于,調(diào)用 DriverManager.getConnection() 方法時,傳入的URL不同:

  • Db2: jdbc:db2://localhost:50000/sample
  • MySQL: jdbc:mysql://localhost:3306/repo

更確切的說,只是協(xié)議的不同: db2 VS. mysql 。

我們知道,JDBC是一套標準,各個廠商分別有著自己的實現(xiàn),也就是各自的JDBC驅(qū)動。這也就是為什么一開始,我們就先引入Db2和MySQL的JDBC驅(qū)動。

JDBC中幾個重要的類:

  • java.sql.DriverManager
  • java.sql.Connection
  • java.sql.Statement
  • java.sql.ResultSet

注意: Connection 、 StatementResultSet 都是需要關(guān)閉的,一種方法是在 finally 塊里顯式調(diào)用其 close() 方法。本例中,使用了Java 7引入的 try() 塊來自動釋放資源(它們都實現(xiàn)了 AutoCloseable 接口)。

class.forName()

以前我們學(xué)習(xí)JDBC的時候,被告知第一步要先使用 Class.forName() 方法,導(dǎo)入特定的JDBC驅(qū)動。

但是通過本文的兩個例子,我們看到,即使省略這一步,也沒有問題,DriverManager能夠自動找到合適的驅(qū)動。

那么問題來了:

  • 調(diào)用 Class.forName() 方法,到底干了什么?
  • 為什么本文中不調(diào)用該方法也沒問題?

我們知道,如果某個類之前沒有被使用過,則調(diào)用 Class.forName() 方法,會做幾件事情,包括實例化該類的Class對象,并且執(zhí)行其static塊,等等。

對于JDBC驅(qū)動,以Db2驅(qū)動為例,查看 com.ibm.db2.jcc.DB2Driver 類,可以找到如下代碼:

    static {
        DB2BaseDataSource.class.getClass();

        try {
            registeredDriver__ = new DB2Driver();
            DriverManager.registerDriver(registeredDriver__);
        } catch (SQLException var1) {
            ap.f = lr.a(b7.a(DB2Driver.class, (ds)null, ErrorKey.ERROR_REGISTER_WITH_DRIVER_MGR, "10032"), ap.f);
        }
    }

可見,調(diào)用了 DriverManager.registerDriver() 方法注冊了Db2的驅(qū)動。

同理,對于MySQL,它的驅(qū)動類 com.mysql.cj.jdbc.Driver (是 com.mysql.jdbc.Driver 類的父類)里有如下代碼:

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }

可見,類似的,也是調(diào)用了 DriverManager.registerDriver() 方法注冊了MySQL的驅(qū)動。

由此,我們知道,調(diào)用 class.forName() 方法來裝載驅(qū)動,其作用是注冊了該驅(qū)動。

那么為什么本文中不調(diào)用方法也沒問題呢?

java.sql.Connection 是一個接口,我們通過打印 connection.getClass().getName() 來看看具體的類名(參見代碼中的注釋部分)。

  • Db2: com.ibm.db2.jcc.t4.b
  • MySQL: com.mysql.cj.jdbc.ConnectionImpl

可見,即使不通過 class.forName() 方法來顯式注冊指定的驅(qū)動,而直接調(diào)用 DriverManager.getConnection() 方法,則根據(jù)傳入的URL不同,也能獲取正確的數(shù)據(jù)庫連接。

可以去查看DriverManager的源碼,大致如下:

......
        for (DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if (isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }
......

也就是說,它會先生成驅(qū)動的列表,然后遍歷列表,根據(jù)傳入的URL,嘗試使用當(dāng)前驅(qū)動來連接數(shù)據(jù)庫,如果能連上,就OK,否則就嘗試下一個驅(qū)動。

當(dāng)然,如果調(diào)用 Class.forName() 方法顯式注冊驅(qū)動,則會把驅(qū)動類放到列表的第一個,優(yōu)先使用它來連接數(shù)據(jù)庫。

到此這篇關(guān)于關(guān)于JDBC的class.forName()問題的文章就介紹到這了,更多相關(guān)JDBC的class.forName()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL深入淺出掌握觸發(fā)器用法

    MySQL深入淺出掌握觸發(fā)器用法

    觸發(fā)器是SQLserver提供給程序員和數(shù)據(jù)分析員來保證數(shù)據(jù)完整性的一種方法,它是與表事件相關(guān)的特殊的存儲過程,事件是在 MySQL 5.1后引入的,有點類似操作系統(tǒng)的計劃任務(wù),但是周期性任務(wù)是內(nèi)置在MySQL服務(wù)端執(zhí)行的
    2022-05-05
  • MySQL數(shù)據(jù)庫查詢排序方式

    MySQL數(shù)據(jù)庫查詢排序方式

    這篇文章主要介紹了MySQL數(shù)據(jù)庫查詢排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 解析SQL Server 視圖、數(shù)據(jù)庫快照

    解析SQL Server 視圖、數(shù)據(jù)庫快照

    在程序開發(fā)過程中,任何一個項目都離不開數(shù)據(jù)庫,這篇文章給大家詳細介紹SQL Server 視圖、數(shù)據(jù)庫快照相關(guān)內(nèi)容,需要的朋友可以參考下
    2015-08-08
  • MySQL中“:=”和“=”的區(qū)別淺析

    MySQL中“:=”和“=”的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于MySQL中":="和"="區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Can''t connect to local MySQL through socket ''/tmp/mysql.sock''解決方法

    Can''t connect to local MySQL through socket ''/tmp/mysql.so

    今天小編就為大家分享一篇關(guān)于Can't connect to local MySQL through socket '/tmp/mysql.sock'解決方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 使用MySQL進行千萬級別數(shù)據(jù)查詢的技巧分享

    使用MySQL進行千萬級別數(shù)據(jù)查詢的技巧分享

    這篇文章主要介紹了如何使用MySQL進行千萬級別數(shù)據(jù)查詢的技巧,文中通過代碼示例給大家講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • MySQL全面瓦解之查詢的過濾條件詳解

    MySQL全面瓦解之查詢的過濾條件詳解

    這篇文章主要給打大家介紹了關(guān)于MySQL全面瓦解之查詢的過濾條件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • MySQL系列之八 MySQL服務(wù)器變量

    MySQL系列之八 MySQL服務(wù)器變量

    其中有些參數(shù)支持運行時修改,會立即生效;有些參數(shù)不支持,且只能通過修改配置文件,并重啟服務(wù)器程序生效;有些參數(shù)作用域是全局的,且不可改變;有些可以為每個用戶提供單獨(會話)的設(shè)置
    2021-07-07
  • CentOS7.x?安裝mysql5.7?XtraBackUp備份工具使用命令詳解

    CentOS7.x?安裝mysql5.7?XtraBackUp備份工具使用命令詳解

    這篇文章主要介紹了CentOS7.x?安裝mysql5.7?XtraBackUp備份工具使用,本文給大家介紹了mysql安裝過程及命令使用方法,需要的朋友可以參考下
    2022-04-04
  • 安裝MySQL phpMyAdmin cpolar實現(xiàn)遠程訪問連接的操作步驟

    安裝MySQL phpMyAdmin cpolar實現(xiàn)遠程訪問連接的操作步驟

    這篇文章主要給大家介紹了安裝 MySQL phpMyAdmin cpolar實現(xiàn)遠程訪問連接的流程步驟,文中有詳細的圖文介紹,具有一定的參考價值,需要的朋友可以參考下
    2023-08-08

最新評論