【问题标题】:Java Class.forName, JDBC connection loading driver [duplicate]Java Class.forName,JDBC 连接加载驱动程序 [重复]
【发布时间】:2013-08-06 04:37:29
【问题描述】:

在进行简单的 JDBC 连接时,所有资源都给出相同的代码

String driver = "com.mysql.jdbc.Driver";
Statement statement = null; 
Class.forName(driver); 
Connection conn  = DriverManager.getConnection(url + dbName,userName, password);

但我们实际上与“Class.forName(driver)”无关。我们没有将它存储在任何地方。 这有什么用,因为我们与 Class.forName(driver) 的返回无关。

【问题讨论】:

标签: java mysql jdbc


【解决方案1】:

Class.forName("driver.class"); 加载指定的 JDBC 驱动程序。当驱动程序加载时,它也会向DriverManager 注册自己。因此,当您调用DriverManager#getConnection() 时,您可以通过之前加载的驱动程序建立Connection

DriverManager#getConnection()

当调用 getConnection 方法时,DriverManager 将尝试从初始化时加载的驱动程序和使用与当前小程序或应用程序相同的类加载器显式加载的驱动程序中找到合适的驱动程序。

【讨论】:

    【解决方案2】:

    使用Class.forName(..) 加载类。大多数java.sql.Driver 实现(使用静态初始化程序)在加载类时将自己注册到java.sql.DriverManager 实现。有关详细信息,请参阅 JDBC 4.1 规范中的第 9.2 节:

    JDBC 驱动程序必须实现Driver 接口,并且实现必须 包含将在加载驱动程序时调用的静态初始化程序。这 初始化器用DriverManager注册一个自己的新实例,

    注册后,您可以使用该驱动程序创建连接。

    但是,从 JDBC 4.0 (Java 6) 开始,不再需要以这种方式加载符合 JDBC 4.0 规范的驱动程序,因为 DriverManager 本身将使用 ServiceLoader 机制负责定位和加载 JDBC 驱动程序.请参阅 JDBC 4.1 规范的第 9.2.1 节:

    DriverManager.getConnection 方法已得到增强,以支持 Java 标准版服务提供者机制。 JDBC 4.0 驱动程序必须包括 文件META-INF/services/java.sql.Driver。此文件包含的名称 java.sql.Driver 的 JDBC 驱动实现。

    【讨论】:

      【解决方案3】:

      嗯,它确实有一个副作用——它将由字符串名称指定的驱动程序加载到内存中。

      在 Java 中,类仅在真正需要使用时才加载。

      所以Class.forName() 将导致类加载器“读取”字节码并将类定义加载到 JVM 的内存中。

      现在,当这种情况发生时,这个类(驱动程序应该有一个)的静态初始化块被执行(它应该是静态的,因为我们并没有真正创建这个类的对象)。

      编写此静态初始化块,以便在 DriverManager 中注册驱动程序。

      这是“按书本”的解释。当然这个 API 不是那么清楚也不明显。 可以明确地做到这一点:

      Driver driver = (Driver)Class.forName("com.mysql.jdbc.Drivercom.mysql.jdbc.Driver").newInstance();
      DriverManager.registerDriver(driver);
      

      自 Java 6 起,不应再使用此机制。 阅读here 了解加载驱动程序的新方法。

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        class.forName() 使 ClassLoader 将类加载到内存中。 JDBC 驱动程序类包含一个静态初始化程序块,该程序块将驱动程序注册到 DriverManager 以供以后参考。连接时 DriverManager 使用数据库参数查找正确的驱动程序

        【讨论】:

          【解决方案5】:

          Class.forName() 尝试加载指定的类。在 JDBC 的早期版本中,这是必要的,因为 Driver 类要求以这种方式加载该类。这已经很久没有要求了。

          省掉电话,不会有什么不好的事情发生。

          出于某种原因,教程和示例仍然沿用旧方式。

          手动加载类的唯一微小好处是,它可以准确地告诉您问题所在,以防您在类路径中没有正确的类。

          【讨论】:

          • 谢谢。 @Bohermain。我现在清楚了。
          • 我正在使用 java EE 8,但没有 Class.forName("mysqlmodule") 仍然无法建立连接
          【解决方案6】:

          这是 com.mysql.jdbc.Driver 向 DriverManager 注册自身的部分

          //
              // Register ourselves with the DriverManager
              //
              static {
                  try {
                      java.sql.DriverManager.registerDriver(new Driver());
                  } catch (SQLException E) {
                      throw new RuntimeException("Can't register driver!");
                  }
              }
          

          需要注意的是,从 1.6 版开始,无需使用 Class.forName() 显式加载 JDBC 驱动程序,DriverManager 可以使用 Service Provider 机制自动检测 JDBC 4.0 驱动程序。 JDBC驱动类名写在META-INF/services/java.sql.Driver文件中

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-12-07
            • 2014-05-17
            • 2012-02-28
            • 2016-09-07
            • 2011-08-24
            • 2014-08-19
            相关资源
            最近更新 更多