最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決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()

以前我們學習JDBC的時候,被告知第一步要先使用 Class.forName() 方法,導入特定的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,嘗試使用當前驅(qū)動來連接數(shù)據(jù)庫,如果能連上,就OK,否則就嘗試下一個驅(qū)動。

當然,如果調(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)文章

  • asp+mysql+utf8 網(wǎng)頁出現(xiàn)亂碼問題的解決方法

    asp+mysql+utf8 網(wǎng)頁出現(xiàn)亂碼問題的解決方法

    無論在網(wǎng)頁中加多少UTF8的定義,顯示的結(jié)果都還是會有一些小格子,反而定義為gb2312,顯示完全正常
    2014-03-03
  • 一文帶你了解Mysql主從同步原理

    一文帶你了解Mysql主從同步原理

    本文主要講解了Mysql主從同步原理,主從同步可以擴展數(shù)據(jù)庫的負載能力、容錯還可以數(shù)據(jù)備份等。想要了解相關(guān)內(nèi)容的朋友可以閱讀這篇文章
    2021-08-08
  • MySQL主從復制的原理及配置方法(比較詳細)

    MySQL主從復制的原理及配置方法(比較詳細)

    MySQL 的數(shù)據(jù)庫的高可用性的架構(gòu)大概有以下幾種:集群,讀寫分離,主備。而后面兩種都是通過復制來實現(xiàn)的。下面將簡單介紹復制的原理及配置,以及一些常見的問題
    2014-05-05
  • MYSQL之on和where的區(qū)別解讀

    MYSQL之on和where的區(qū)別解讀

    這篇文章主要介紹了MYSQL之on和where的區(qū)別解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • mysql中的跨庫關(guān)聯(lián)查詢方法

    mysql中的跨庫關(guān)聯(lián)查詢方法

    這篇文章主要介紹了mysql中的跨庫關(guān)聯(lián)查詢方法,需要的朋友可以參考下
    2017-05-05
  • 配置MySQL與卸載MySQL實例操作

    配置MySQL與卸載MySQL實例操作

    我們主要介紹的是正確通過rpm包安裝、對MySQL進行配置與卸載的實際操作步驟,以下就是文章的具體內(nèi)容描述,望你會有所收獲。
    2010-08-08
  • MySQL開啟Slow慢查詢的方法示例

    MySQL開啟Slow慢查詢的方法示例

    這篇文章主要給大家介紹了關(guān)于MySQL開啟Slow慢查詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-02-02
  • mysql community server 8.0.12安裝配置方法圖文教程

    mysql community server 8.0.12安裝配置方法圖文教程

    這篇文章主要為大家詳細介紹了mysql community Server 8.0.12安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • MySQL5.7如何修改root密碼

    MySQL5.7如何修改root密碼

    這篇文章主要為大家詳細介紹了MySQL5.7修改root密碼的相關(guān)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Mysql臨時變量的具體使用

    Mysql臨時變量的具體使用

    本文主要介紹了Mysql臨時變量的具體使用,臨時變量有分為用戶變量和會話變量,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08

最新評論

温泉县| 北流市| 湄潭县| 雷州市| 永宁县| 前郭尔| 屏南县| 永城市| 墨脱县| 剑河县| 太保市| 台东县| 噶尔县| 本溪| 余江县| 仁化县| 炎陵县| 喀喇沁旗| 措美县| 霍邱县| 东方市| 大邑县| 昆山市| 阿坝县| 当雄县| 巴彦县| 台南县| 铜山县| 兰州市| 濮阳市| 板桥市| 洞头县| 丁青县| 安宁市| 云梦县| 越西县| 西乌| 达孜县| 岑溪市| 江达县| 体育|