Java 加载驱动程序和注册驱动程序之间的区别

Java 加载驱动程序和注册驱动程序之间的区别,java,jdbc,database-connection,Java,Jdbc,Database Connection,我对JDBC非常陌生,我已经编写了一个小程序来检查已注册的驱动程序。我想做以下几件事 我在没有加载任何驱动程序的情况下检查了寄存器的数量: 我原以为它不会给我任何惊喜,它给了3个司机注册 我使用Class.forName()加载了一个驱动程序 我原以为它会给我四个车手的,但又一次让我大吃一惊,它只显示了三个车手 最后,我使用DriverManager注册驱动程序 现在它显示了四个驱动程序 谁能帮我理解这里发生了什么。我的问题如下 默认情况下是否加载/注册了这三个驱动程序 不会使用class.fo

我对JDBC非常陌生,我已经编写了一个小程序来检查已注册的驱动程序。我想做以下几件事

  • 我在没有加载任何驱动程序的情况下检查了寄存器的数量:

    我原以为它不会给我任何惊喜,它给了3个司机注册

  • 我使用Class.forName()加载了一个驱动程序

    我原以为它会给我四个车手的,但又一次让我大吃一惊,它只显示了三个车手

  • 最后,我使用DriverManager注册驱动程序

    现在它显示了四个驱动程序

  • 谁能帮我理解这里发生了什么。我的问题如下

  • 默认情况下是否加载/注册了这三个驱动程序
  • 不会使用
    class.forName
    注册驱动程序来加载类吗?(根据我的经验,我猜答案不是这个,我问这个只是为了确定)如果不是,那么加载类只是为了寻求类似(DriverManager等)的推理实现
  • 最后,加载驱动程序和注册驱动程序之间有什么区别
  • 我已经列出了程序和输出,供您参考

    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Enumeration;
    import oracle.jdbc.driver.OracleDriver;
    
    class Test3{
     public static void main(String[] args) throws Exception{
    
         //checking for registered drivers
         System.out.println("Drivers registered initially");
         Enumeration enumm = DriverManager.getDrivers();
         int count=1;
         while(enumm.hasMoreElements()){
             Driver dr=(Driver)enumm.nextElement();
             System.out.println(count+" "+dr);
             count++;
         }
    
         //loading the driver
         Class.forName("oracle.jdbc.driver.OracleDriver");
         System.out.println("\n\nDrivers after class loading");
         enumm = DriverManager.getDrivers();
         count=1;
         while(enumm.hasMoreElements()){
             Driver dr=(Driver)enumm.nextElement();
             System.out.println(count+" "+dr);
             count++;
         }
    
         //After Registering driver
         OracleDriver odr= new OracleDriver();
         DriverManager.registerDriver(odr);
         System.out.println("\nAfter registering oracle driver");
         enumm = DriverManager.getDrivers();
         count=1;
         while(enumm.hasMoreElements()){
             Driver dr=(Driver)enumm.nextElement();
             System.out.println(count+" "+dr);
             count++;
         }
    
    }
    }
    
    输出:

    Drivers registered initially
    
    1 sun.jdbc.odbc。JdbcOdbcDriver@2c84d9

    2 oracle.jdbc。OracleDriver@8bdcd2

    3 com.mysql.jdbc。Driver@1f31ad9

    Drivers after class loading
    
    After registering oracle driver
    
    1 sun.jdbc.odbc。JdbcOdbcDriver@2c84d9

    2 oracle.jdbc。OracleDriver@8bdcd2

    3 com.mysql.jdbc。Driver@1f31ad9

    Drivers after class loading
    
    After registering oracle driver
    
    1 sun.jdbc.odbc。JdbcOdbcDriver@2c84d9

    2 oracle.jdbc。OracleDriver@8bdcd2

    3 com.mysql.jdbc。Driver@1f31ad9

    Drivers after class loading
    
    After registering oracle driver
    

    4.oracle.jdbc.driver。OracleDriver@167acf2

    从JDK6开始,如果JVM在类路径中找到任何驱动程序类,JDBC驱动程序将自动加载。JDK6中不需要Class.forName语句。这就是为什么要获得驱动程序,因为它们位于类路径中,由JVM加载。

    JDBC规范要求兼容的驱动程序在加载时(使用静态初始值设定项块)向
    java.sql.DriverManager注册它们自己。您应该永远不必自己注册驾驶员

    从JDBC4.0(Java6)开始,JDBC驱动程序需要指定一个服务定义,声明驱动程序提供的所有
    Java.sql.Driver
    实现(通常是一个)。这是通过文件
    META-INF/services/java.sql.Driver
    完成的

    DriverManager
    将在类路径上查询此文件的所有实例(使用并加载这些文件中包含的所有驱动程序实现)。由于需要(兼容的)驱动程序来注册自身,因此所有这些实现现在都在
    DriverManager
    中注册

    因此:

  • 不再需要使用
    Class.forName(…);
    加载驱动程序(除非驱动程序不符合JDBC 4)
  • 您永远不必在
    DriverManager
    中手动注册驱动程序(除非驱动程序不符合JDBC 1,或者是专门为不注册自身而构建的)

  • 在您的特定代码中,您有三个符合JDBC 4的驱动程序(至少在服务定义方面),因此它们会自动加载。执行
    Class.forName(…)
    没有效果,因为类已经加载(因此不会再次加载)。当您手动注册驱动程序时(正如我之前所说,您应该永远不要这样做),它将向已注册的驱动程序列表中添加一个额外的实例。

    您使用哪个JDK?我使用的是JDK-7。我忘了提到这一点。这只适用于jar中包含所需服务定义的符合JDBC 4的驱动程序(因此,旧驱动程序或不符合要求的驱动程序不会(始终)自动加载)。我的意思是该功能是在JDK6中添加的,因此在JDK 7中肯定会相同。。检查此处的链接是的,我在参考库中确实有一些jar文件。删除该功能后,输出仅减少到1 sun.jdbc.odbc。JdbcOdbcDriver@16fd0b7.因此,我可以考虑ODBC驱动程序是否加载了默认的.class?FordNeX(“…”)。加载该类,但是否使用forName加载该类,甚至在DriverManager中注册驱动程序?“JDBC 1兼容”?@YoushaAleayoub第一个JDBC规范中已经指定了驱动程序向
    DriverManager
    注册的要求,因此为“JDBC 1兼容”。