JDBC: why 'Class.forName' at first

JDBC: why 'Class.forName' at first

First, here is the following basic code:

 1  package  com.googlesites.qslbinghamton.corejava.database;
 2 
 3  import  java.sql.Connection;
 4  import  java.sql.DriverManager;
 5  import  java.sql.ResultSet;
 6  import  java.sql.SQLException;
 7  import  java.sql.Statement;
 8 
 9  public   class  MySqlConn {
10       public   static  Connection getConnection()  throws  Exception {
11          String driver  =   " com.mysql.jdbc.Driver " ;
12          String url  =   " jdbc:mysql://localhost/t2 " ;
13          String username  =   " root " ;
14          String password  =   "12345678 " ;
15 
16          Class.forName(driver);
17          Connection conn  =  DriverManager.getConnection(url, username, password);
18           return  conn;
19      }
20 
21       public   static   void  main(String[] args) {
22          Connection conn  =   null ;
23          Statement stmt  =   null ;
24          ResultSet rs  =   null ;
25           try  {
26              conn  =  getConnection();
27              System.out.println( " conn= "   +  conn);
28               //  prepare query
29              String query  =   " select * from Employee " ;
30               //  create a statement
31              stmt  =  conn.createStatement();
32               //  execute query and return result as a ResultSet
33              rs  =  stmt.executeQuery(query);
34               //  extract data from the ResultSet
35               while  (rs.next()) {
36                  String id  =  rs.getString( 1 );
37                  String username  =  rs.getString( 2 );
38 
39                  System.out.println( " id= "   +  id);
40                  System.out.println( " name= "   +  username);
41                  System.out.println( " --------------- " );
42              }
43          }  catch  (Exception e) {
44              e.printStackTrace();
45              System.exit( 1 );
46          }  finally  {
47               //  release database resources
48               try  {
49                  rs.close();
50                  stmt.close();
51                  conn.close();
52              }  catch  (SQLException e) {
53                  e.printStackTrace();
54              }
55          }
56      }
57  }
58 

Here is a trivial question, why Class.forName in the first place.
Now, let's take a look at class com.mysql.jdbc.Driver source file:

 1  package  com.mysql.jdbc;
 2 
 3  import  java.sql.SQLException;
 4 
 5  /**
 6   * The Java SQL framework allows for multiple database drivers. Each driver
 7   * should supply a class that implements the Driver interface
 8   * 
 9   * <p>
10   * The DriverManager will try to load as many drivers as it can find and then
11   * for any given connection request, it will ask each driver in turn to try to
12   * connect to the target URL.
13   * 
14   * <p>
15   * It is strongly recommended that each Driver class should be small and
16   * standalone so that the Driver class can be loaded and queried without
17   * bringing in vast quantities of supporting code.
18   * 
19   * <p>
20   * When a Driver class is loaded, it should create an instance of itself and
21   * register it with the DriverManager. This means that a user can load and
22   * register a driver by doing Class.forName("foo.bah.Driver")
23   * 
24   *  @see  org.gjt.mm.mysql.Connection
25   *  @see  java.sql.Driver
26   *  @author  Mark Matthews
27   *  @version  $Id$
28    */
29  public   class  Driver  extends  NonRegisteringDriver  implements  java.sql.Driver {
30       //  ~ Static fields/initializers
31       //  ---------------------------------------------
32 
33       //
34       //  Register ourselves with the DriverManager
35       //
36       static  {
37           try  {
38              java.sql.DriverManager.registerDriver( new  Driver());
39          }  catch  (SQLException E) {
40               throw   new  RuntimeException( " Can't register driver! " );
41          }
42      }
43 
44       //  ~ Constructors
45       //  -----------------------------------------------------------
46 
47       /**
48       * Construct a new driver and register it with DriverManager
49       * 
50       *  @throws  SQLException
51       *             if a database error occurs.
52        */
53       public  Driver()  throws  SQLException {
54           //  Required for Class.forName().newInstance()
55      }
56  }
57 


Take a close look in class Driver's static block:

java.sql.DriverManager.registerDriver( new  Driver());


It ensures the new created Driver object is registered every time after Driver class is created or Driver instance is created.

Class.forName(driver); make sure the code in static block run at first which means a new Driver class object is created during the compile time.

For better understanding, here is a sample program which have a static block in the class

 

class  A {
    
static  {
        System.out.println(
" Class A loaded " );
    }

    
public  A() {
        System.out.println(
" create a instance of A " );
    }
}

public   class  Main {

    
public   static   void  main(String[] args)  throws  Exception {
        Class.forName(
" com.javaye.A " );
    }
}

The output from class Main is

Class A loaded


Now, change the above code a little bit in public static void main function: only initiate class A a=null.

 

 1  class  A {
 2       static  {
 3          System.out.println( " Class A loaded " );
 4      }
 5 
 6       public  A() {
 7          System.out.println( " create a instance of A " );
 8      }
 9  }
10 
11  public   class  Main {
12 
13       public   static   void  main(String[] args)  throws  Exception {
14          A a  =   null ;
15 
16      }
17  }

There is no output at this time. This is because only with a variable name 'a' doesn't change the fact that no new object from class 'A' is created and the static block doesn't
run neither.

Change the code again:


 1  class  A {
 2       static  {
 3          System.out.println( " Class A loaded " );
 4      }
 5 
 6       public  A() {
 7          System.out.println( " create a instance of A " );
 8      }
 9  }
10 
11  public   class  Main {
12 
13       public   static   void  main(String[] args)  throws  Exception {
14          A a  =   new  A();
15          A a2  =   new  A();
16      }
17  }

The outputs are:
Class A loaded
create a instance of A
create a instance of A

Clearly, with new A(), static block only runs once(The basic concept of static) and constructor of A runs twice as 2 objects are creates.



你可能感兴趣的:(JDBC: why 'Class.forName' at first)