Java, Only Java!

          統計

          留言簿(20)

          積分與排名

          好友空間

          文檔技巧

          閱讀排行榜

          評論排行榜

          注冊mySQL到JDBC驅動程序方法淺談

          一、注冊方法(4種)

          1)服務提供者框架:

          符合JDBC 4.0規范的驅動程序包含了一個文件META-INF/services/java.sql.Driver,在這個文件中提供了JDBC驅動實現的類名。

          例如:mysql-connector-java-5.1.40-bin.jar文件中就可以找到java.sql.Driver文件,用文本編輯器打開文件就可以看到:com.mysql.jdbc.Driver類。

          JVM的服務提供者框架在啟動應用時就會注冊服務,例如:mySQL的JDBC驅動就會被注冊,而原代碼中的Class.forName("com.mysql.jdbc.Driver")仍然可以存在,但是不會起作用。

           

          2)Class.forName("com.mysql.jdbc.Driver");

          通過對類com.mysql.jdbc.Driver初始化,執行靜態初始化代碼,調用DriverManager注冊JDBC驅動。

          注:通過setProperty的測試,確認類com.mysql.jdbc.Driver也沒有加載,那么靜態初始化代碼肯定被執行了,但是如果服務提供者框架已經注冊的服務,這里注冊會失敗,編程的預期是這樣的,可是理論上DriverManager.registerDriver可以重復注冊的,為什么這里不能重復注冊呢?

          3)System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver";);

          設置JVM的系統屬性,當JVM第一次加載DriverManager類時,會執行類的靜態初始化代碼,代碼中調用loadInitialDrivers()方法,就會加載設置的屬性對應的類,執行類的靜態初始化代碼完成注冊。

          注:因為注冊的機制無法深入理解,只知道沒有加載過的類可以注冊成功,加載過的就不能重復注冊了。

          注:setProperty必須在DriverManager第一次運行前才有效,說明”服務提供者”框架注冊服務時并沒有加載類,因為一旦加載類就會執行類的靜態初始化代碼,那么注冊JDBC驅動就一定會調用DriverManager類的靜態初始化代碼,那么setProperty就會失效,所以說明注冊服務是不加載類的。

          4)DriverManager.registerDriver(new com.mysql.jdbc.Driver());

          其實前面的2)和3)最終都是通過這個方法注冊的,但是這個方法就可以重復注冊。

          注:對于重復注冊后,建立鏈接時使用哪個驅動我就不明白了,可以取消注冊,取消的關鍵字是基于創建的對象的,所以就算重名也不會出錯。

          注:這種注冊方式沒有前面幾種好,因為這種注冊方式會在代碼中與需要注冊的驅動程序的類綁定,前面都可以通過配置參數實現注冊。

          二、各自特點:

          1)全自動。只要提供符合規范的JAR文件就可以了。

          2)利用反射機制,將驅動類注入到代碼中,不需要與代碼綁定。

          3)基于系統的屬性設置方法,將驅動類注入到代碼中,但是好像只能綁定一個JDBC驅動。

          4)最終的注冊機制。會出現重復注冊,但是好像對程序沒影響,還需要與代碼綁定,驅動變了,必須修改代碼,維護成本過高,當然也是靈活性最好,管理最方便的。

          以下是測試代碼:

          import java.sql.Connection;
          import java.sql.Driver;
          import java.sql.DriverManager;
          import java.sql.SQLException;
          import java.util.Enumeration;
          
          /**
           * @author 朱遠翔.Tom 測試JDBC驅動注冊
           */
          public class JDBCDriverTest {
          
              public static void main(String[] args) {
                  Driver aDriver;
                  Connection connection;
                  Enumeration em;
                  // “org.gjt.mm.mysql.Driver”是“com.mysql.jdbc.Driver”的子類,其構造函數就是調用父類的構造函數。
                  String driverString = "com.mysql.jdbc.Driver";
                  // String driverString = "org.gjt.mm.mysql.Driver";
                  String url = "jdbc:mysql://localhost/ElectricalStore?useSSL=false";
                  String username = "admin";
                  String password = "123456";
          
                  try {
                     // 將DriverManager的日志流輸出到Console窗口中,方便監控
                     // DriverManager.setLogStream(System.out);
                     // DriverManager.println("------DriverManager logs start!------");
          
                     // 只是設置了一個JVM的系統屬性,并不建立JDBC驅動程序。
                      // 建立JDBC驅動是依賴系統第一次調用DriverManager類時,執行了這個類的靜態初始化代碼中的loadInitialDrivers(),
                      // 加載驅動的方法會把設置的jdbc.drivers屬性對應的驅動類通過DriverManager.registerDriver注冊到JDBC中。
                      // 因此,必須放在DriverManager被第一次調用之間,也就是需要將前面那兩行代碼注釋掉
                      System.out.println("1.1> Tried to use setProperty.");
                      System.setProperty("jdbc.drivers", driverString);
                      System.out.println("---List of all jdbc drivers---");
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("There is no JDBC drivers");
                      } else {
                          while (em.hasMoreElements()) {
                              aDriver = (Driver) em.nextElement();
                              System.out.println(aDriver);
                          }
                      }
          
                      System.out.println("1.2> we tried to use Class.forName");
                      // Class.forName(driverString)在JavaSE 6.0后符合JDBC 4.0規范的驅動可以不用
                      // 基于服務提供機制( Service Provider mechanism),
                      // 系統會自動搜索mysql-connector-java-???-bin.jar中的META-INF/services/java.sql.Driver
                      // 這個文件會包含mysql jdbc驅動程序的入口:com.mysql.jdbc.Driver
                      // 應用程序調用Class.forName()也不會出錯,只是什么都不會執行。
                      // 因為Class.forName()就是執行靜態初始化代碼,已經初始化過的類就無法激活這段代碼了
                      // System.setProperty("jdbc.drivers",driverString);與Class.forName()一樣。
                      try {
                          Class.forName("com.mysql.fabric.jdbc.FabricMySQLDriver");
                      } catch (ClassNotFoundException e) {
                          System.out.println("Driver not found");
                      }
          
                      System.out.println("---List of all jdbc drivers---");
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("There is no JDBC drivers");
                      } else {
                          while (em.hasMoreElements()) {
                              aDriver = (Driver) em.nextElement();
                              System.out.println(aDriver);
                          }
                      }
          
                      System.out.println("1.3> we tried to use DriverManager.registerDriver");
                      // 手工注冊mySQL的JDBC驅動程序,也就出現了與mySQL綁定過緊的問題,如果以后需要更換驅動,就需要修改代碼。
                      // 系統容許出現重復注冊同樣的jdbc驅動類
                      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                      DriverManager.registerDriver(new com.mysql.fabric.jdbc.FabricMySQLDriver());
                      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
          
                      System.out.println("---List of all jdbc drivers---");
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      while (em.hasMoreElements()) {
                          aDriver = (Driver) em.nextElement();
                          System.out.println(aDriver);
                      }
          
                      System.out.println("<1.5> Deregister all JDBC drivers");
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      while (em.hasMoreElements()) {
                          aDriver = (Driver) em.nextElement();
                          DriverManager.deregisterDriver(aDriver); // 將已經注冊的驅動程序取消注冊
                      }
          
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("2.1> Now, there is no JDBC driver");
                      }
          
                      System.out.println("2.2> we tried to use Class.forName again");
                      try {
                          Class.forName(driverString);
                      } catch (ClassNotFoundException e) {
                          System.out.println("Driver not found");
                      }
                      try {
                          Class.forName("com.mysql.fabric.jdbc.FabricMySQLDriver");
                      } catch (ClassNotFoundException e) {
                          System.out.println("Driver not found");
                      }
                      try {
                          Class.forName(driverString);
                      } catch (ClassNotFoundException e) {
                          System.out.println("Driver not found");
                      }
          
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("There is no JDBC drivers");
                      } else {
                          System.out.println("---List of all jdbc drivers---");
                          while (em.hasMoreElements()) {
                              aDriver = (Driver) em.nextElement();
                              System.out.println(aDriver);
                          }
                      }
          
                      System.out.println("2.3> we tried to use setProperty again");
                      System.setProperty("jdbc.drivers", "com.mysql.fabric.jdbc.FabricMySQLDriver");
          
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("There is no JDBC drivers");
                      } else {
                          System.out.println("---List of all jdbc drivers---");
                          while (em.hasMoreElements()) {
                              aDriver = (Driver) em.nextElement();
                              System.out.println(aDriver);
                          }
                      }
          
                      System.out.println("2.3> Tried to use DriverManager.registerDriver again");
          
                      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                      DriverManager.registerDriver(new com.mysql.fabric.jdbc.FabricMySQLDriver());
                      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
          
                      System.out.println("---List of all jdbc drivers---");
                      em = DriverManager.getDrivers(); // 獲取已加載JDBC驅動程序的Enumeration
                      if (!em.hasMoreElements()) {
                          System.out.println("There is no JDBC drivers");
                      } else {
                          while (em.hasMoreElements()) {
                              aDriver = (Driver) em.nextElement();
                              System.out.println(aDriver);
                          }
                      }
          
                      System.out.print("3.1> Tried to establish a connection: ");
                      connection = DriverManager.getConnection(url, username, password);
                      System.out.println(connection);
                  } catch (SQLException e) {
                      System.out.println("Cannot registered the mysql jdbc driver");
                  }
          
                  System.out
                          .println("jdbc.drivers property: " + System.getProperty("jdbc.drivers", "nothing"));
          
              }
          
          }

          posted on 2016-10-05 20:16 zYx.Tom 閱讀(976) 評論(0)  編輯  收藏 所屬分類: 1.Java世界

          主站蜘蛛池模板: 济源市| 绥中县| 沾化县| 滨州市| 嘉鱼县| 桐乡市| 民丰县| 旌德县| 台山市| 车致| 开化县| 咸宁市| 威远县| 洛扎县| 安吉县| 通河县| 南安市| 万宁市| 万州区| 上饶县| 浠水县| 兖州市| 安图县| 锡林浩特市| 昆明市| 赣榆县| 宿松县| 喀喇| 丹巴县| 福清市| 专栏| 牟定县| 金山区| 泽库县| 调兵山市| 丁青县| 三河市| 德惠市| 民县| 襄樊市| 阳春市|