JAVA加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)(JDBC)

JAVA加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)(JDBC)

前言

之前,對(duì)Class.forName("com.mysql.jdbc.Driver");這條動(dòng)態(tài)加載JDBC驅(qū)動(dòng)感覺很疑惑,故有了這篇短文。

一、使用JDBC連接MySQL

首先,來(lái)看一下正常使用Java操縱MySql的簡(jiǎn)單代碼邏輯。

    public static boolean connectionMySqlDemo() {
        Connection conn = null;
        try {
            // 1、動(dòng)態(tài)加載mysql驅(qū)動(dòng)
            Class.forName("com.mysql.jdbc.Driver"); 
            // 2、連接數(shù)據(jù)庫(kù)
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"
                    + "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");
            // 3、聲明一個(gè)Statement 用來(lái)執(zhí)行sql語(yǔ)句
            Statement stmt = conn.createStatement();
            
            // 4、執(zhí)行sql語(yǔ)句
            stmt.executeUpdate("create table student(no_id char(20),name varchar(20),primary key(no_id))");
            int result = stmt.executeUpdate("insert into student(no_id,name) values('1','fxleyu')");
            if (result > 0) {
                ResultSet rs = stmt.executeQuery("select * from student");
                while (rs.next()) {
                    System.out.println(rs.getString(1));
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 5、關(guān)閉數(shù)據(jù)庫(kù)
            if (conn != null) {
                try {
                    conn.close();
                    return true;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

        return false;
    }

在上述代碼中,動(dòng)態(tài)加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)那條語(yǔ)句感覺獨(dú)立于其余代碼邏輯。感覺缺少其并無(wú)關(guān)系(當(dāng)然缺少了會(huì)在鏈接數(shù)據(jù)庫(kù)時(shí)報(bào)java.sql.SQLException: No suitable driver found for)。

二、疑惑

上述代碼很容易理解,除了如下Class.forName("com.mysql.jdbc.Driver");。正常理解,該語(yǔ)句只是加載把com.mysql.jdbc.Driver加載到JVM中,沒(méi)不會(huì)產(chǎn)生特殊作用。
閱讀com.mysql.jdbc.Driver代碼,可以發(fā)現(xiàn)其中的隱含邏輯。

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

    /**
     * Construct a new driver and register it with DriverManager
     * 
     * @throws SQLException
     *             if a database error occurs.
     */
    public Driver() throws SQLException {
        // Required for Class.forName().newInstance()
    }
}

原來(lái)該類中有靜態(tài)代碼庫(kù),其加載到JVM時(shí),會(huì)執(zhí)行該靜態(tài)代碼庫(kù)。而該代碼塊會(huì)把該類的對(duì)象實(shí)例自注冊(cè)到DriverManager中。如此第一部分中的第二步就很容易理解了。

// 2、連接數(shù)據(jù)庫(kù)
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"
        + "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");

其就是可以根據(jù)String來(lái)獲得上述加載的驅(qū)動(dòng),從而可以正常訪問(wèn)數(shù)據(jù)庫(kù)。

三、余以為

代碼的邏輯很重要,而Class.forName("com.mysql.jdbc.Driver");單獨(dú)來(lái)看只是一條孤立的語(yǔ)句。沒(méi)有和上下文代碼產(chǎn)生顯示的關(guān)聯(lián),這就導(dǎo)致了余在前言中的疑惑。故,使用Class.forName("com.mysql.jdbc.Driver");來(lái)動(dòng)態(tài)注冊(cè)驅(qū)動(dòng),會(huì)對(duì)當(dāng)前代碼邏輯產(chǎn)生不利影響。

正常的邏輯,Class.forName方法就是加載一個(gè)指定類,并對(duì)該類做一些初始化工作(使用靜態(tài)代碼庫(kù)),其不應(yīng)該做一些其它邏輯,例如動(dòng)態(tài)注冊(cè)驅(qū)動(dòng)。如果需要注冊(cè)驅(qū)動(dòng)時(shí),應(yīng)該讓用戶自己使用DriverManager.registerDriver(new com.mysql.jdbc.Driver());來(lái)顯示注冊(cè)。這樣代碼邏輯會(huì)很清晰。

但在這里使用顯示注冊(cè)并不合適。因?yàn)楫?dāng)new com.mysql.jdbc.Driver()的動(dòng)作中,就有類的加載過(guò)程。在該過(guò)程中,已經(jīng)把該驅(qū)動(dòng)加載到了DriverManager的列表中。而有顯示的注冊(cè)了一次,故DriverManager的列表會(huì)有兩個(gè)com.mysql.jdbc.Driver實(shí)例。也就是說(shuō),MySql的jdbc并不適合用來(lái)進(jìn)行顯示加載。

當(dāng)然,也許使用Class.forName("com.mysql.jdbc.Driver");有MySql團(tuán)隊(duì)自己的考慮,而我當(dāng)前視野并沒(méi)有看到其好處。

四、結(jié)束

Talk is cheap, show me the code. 當(dāng)對(duì)某些代碼邏輯有疑問(wèn)時(shí),不妨查看一下相關(guān)源碼,就會(huì)豁然開朗。自勉。P.S. 第三部分的余以為靈感借鑒于“余晟以為”微信公眾號(hào),很喜歡他那句“我是這么以為的,當(dāng)然你也可以那么以為”。

參考

1、使用源碼下載路徑 http://101.96.8.142/dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.40.tar.gz

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,400評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,136評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,452評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,818評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,997評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,552評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,292評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,510評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,721評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,235評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,480評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容