程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Class.forName("com.mysql.jdbc.Driver") ;,jdbcclass.forname

Class.forName("com.mysql.jdbc.Driver") ;,jdbcclass.forname

編輯:JAVA綜合教程

Class.forName("com.mysql.jdbc.Driver") ;,jdbcclass.forname


try {
    Class.forName("com.mysql.jdbc.Driver") ;   
} catch(ClassNotFoundException e) {   
    System.out.println("找不到驅動程序類 ,加載驅動失敗!");
    // TODO
}

  在上面的代碼中,class.forName("com.mysql.jdbc.Driver");的主要作用是在運行期以反射的方式來檢查JDBC驅動的主類com.mysql.jdbc.Driver是否存在,若不存則表示運行環境中沒有這個驅動,進入catch段。如果你確定一定以及肯定它會存在,可以直接寫成import com.mysql.jdbc.Driver;效果基本是一樣的(只是在編譯期及運行期要都保證此類存在classpath中)所以,以反射形式加載的一個好處是當驅動jar包不存在時,我們可以做更多的操作。(要知道,在很久很久以前,jdbc驅動一般都是放在運行環境的classpath中的,如tomcat/lib)。

  另外一個很重要的原因是解耦。首先要明白JDBC是Java的一種規范,通俗一點說就是JDK在java.sql.*下提供了一系列的接口(interface),但沒有提供任何實現(也就是類)。 所以任何人都可以在接口規范之下寫自己的JDBC實現(如MySQL)。而若調用者也只調用接口上的方法(如我們),那麼當未來有任何變更需要時(例如要從MySQL遷移至Oracle),則理論上不需要對代碼做任何修改就能直接切換(可惜SQL語法沒能統一規范)這意味著什麼?意味著你的代碼中不應該引用任何與實現相關的東西,你的代碼只知道java.sql.*,而不應該知道com.mysql.*或是com.oracle.*,以避免或減少未來切換數據源時對代碼的變更。注意,我們使用的所有其他API包括Connection/Statement/ResultSet等都是java.sql.*的東西,甚至com.mysql.jdbc.Driver類也是:因此,直接import com.mysql.jdbc.Driver;違反了開閉原則(OCP,對擴展開放,對修改關閉)。(有人說我用反射也必須要修改代碼呀,事實上你可以將類名字符串存儲至.properties文件,和數據庫用戶名密碼放在一起,就像Hibernate做的那樣)。

  如果我可以保證JDBC驅動一定在classpath下,是不是可以不寫這段反射代碼,也不引用任何的Driver類?答案是否定的,請看下面這段代碼源自com.mysql.jdbc.Driver

 

package com.mysql.jdbc;
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!");
        }
    }
    ...
}

 

static代碼塊會在類加載時就被執行,也就是當我們執行Class.forName("com.mysql.jdbc.Driver")時(或import com.mysql.jdbc.Driver

  

  反射的使用,讓Java更具有動態特性。一條sql語句查詢,得到一條查詢結果,例如select * from user where id = 1;得到id, userName, email, pwd等字段以及對應的值,但是你的目的不僅僅是得到這些字段,你要將這些字段封裝成User對象,便於後續的使用。

  如果你只有一個User類你可以寫一個util類將這些字段一一賦值給User對象的每個屬性,但是你在項目開發中還有很多實體類,這怎麼辦呢?每個都寫個util類?對象屬性發生變化又得重寫?這時候反射機制就可以實現這個通用的方法,傳入查詢出的ResultSet以及你要的對象Class,通過反射獲取Class中的field list,從ResultSet中獲取對應的值,再使用反射調用Class中對應filed的set方法,完成對對象的封裝。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved