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

解決JDBC的class.forName()問(wèn)題

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

環(huán)境

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

準(zhǔn)備

Db2

在Db2的 sample 數(shù)據(jù)庫(kù)中,創(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ù)庫(kù)中,創(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項(xiàng)目 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>
......

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

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);
        }
    }
}

運(yùn)行程序,結(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);
        }
    }
}

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

1
2

分析

JDBC

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

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

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

我們知道,JDBC是一套標(biāo)準(zhǔn),各個(gè)廠商分別有著自己的實(shí)現(xiàn),也就是各自的JDBC驅(qū)動(dòng)。這也就是為什么一開(kāi)始,我們就先引入Db2和MySQL的JDBC驅(qū)動(dòng)。

JDBC中幾個(gè)重要的類:

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

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

class.forName()

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

但是通過(guò)本文的兩個(gè)例子,我們看到,即使省略這一步,也沒(méi)有問(wèn)題,DriverManager能夠自動(dòng)找到合適的驅(qū)動(dòng)。

那么問(wèn)題來(lái)了:

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

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

對(duì)于JDBC驅(qū)動(dòng),以Db2驅(qū)動(dòng)為例,查看 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);
        }
    }

可見(jiàn),調(diào)用了 DriverManager.registerDriver() 方法注冊(cè)了Db2的驅(qū)動(dòng)。

同理,對(duì)于MySQL,它的驅(qū)動(dòng)類 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!");
        }
    }

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

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

那么為什么本文中不調(diào)用方法也沒(méi)問(wèn)題呢?

java.sql.Connection 是一個(gè)接口,我們通過(guò)打印 connection.getClass().getName() 來(lái)看看具體的類名(參見(jiàn)代碼中的注釋部分)。

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

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

可以去查看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;
                    }
                }
......

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

    這篇文章主要給大家介紹了關(guān)于MySQL中":="和"="區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(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'解決方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • 使用MySQL進(jìn)行千萬(wàn)級(jí)別數(shù)據(jù)查詢的技巧分享

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

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

    MySQL全面瓦解之查詢的過(guò)濾條件詳解

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

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

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

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

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

    安裝MySQL phpMyAdmin cpolar實(shí)現(xiàn)遠(yuǎn)程訪問(wèn)連接的操作步驟

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

最新評(píng)論