连接数据库时 Class.forName("oracle.jdbc.driver.OracleDriver") 的实际用途是啥?

Posted

技术标签:

【中文标题】连接数据库时 Class.forName("oracle.jdbc.driver.OracleDriver") 的实际用途是啥?【英文标题】:What is the actual use of Class.forName("oracle.jdbc.driver.OracleDriver") while connecting to a database?连接数据库时 Class.forName("oracle.jdbc.driver.OracleDriver") 的实际用途是什么? 【发布时间】:2011-12-24 13:59:52 【问题描述】:

命令是什么

Class.forName("oracle.jdbc.driver.OracleDriver")

在连接到 Oracle 数据库时确实如此吗?有没有其他方法可以做同样的事情?

【问题讨论】:

相关:***.com/questions/5992126/loading-jdbc-driver 请注意,您需要在应用程序启动期间只调用一次;在应用程序的生命周期内,您无需每次都在获得连接之前调用它。 @BalusC 假设我在单独的类 A 中有我的连接详细信息,我在类 A 构造函数中调用 Class.forName("oracle.jdbc.driver.OracleDriver"),并创建 A's 对象以获取每个 servlet 的连接字段,其中我需要连接,然后 java 会跳过Class.forName("oracle.jdbc.driver.OracleDriver") 还是会再次加载? 【参考方案1】:

它使用 FQCN(全限定类名)oracle.jdbc.driver.OracleDriver 获取对类对象的引用。

除了确保当前类加载器加载指定的类之外,它在连接到数据库方面没有“做”任何事情。写法没有本质区别

Class<?> driverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
// and
Class<?> stringClass = Class.forName("java.lang.String");

Class.forName("com.example.some.jdbc.driver") 调用出现在使用 JDBC 的遗留代码中,因为that is the legacy way of loading a JDBC driver。

来自The Java Tutorial:

在以前的 JDBC 版本中,要获得连接,首先必须通过调用方法 Class.forName 来初始化 JDBC 驱动程序。此方法需要java.sql.Driver 类型的对象。每个 JDBC 驱动程序都包含一个或多个实现接口 java.sql.Driver 的类。 ... 在您的类路径中找到的任何 JDBC 4.0 驱动程序都会自动加载。 (但是,您必须使用 Class.forName 方法手动加载 JDBC 4.0 之前的所有驱动程序。)

进一步阅读(阅读:问题这是重复的)

What purpose does Class.forName() serve if you don't use the return value? How does Class.forName() work? What does 'Class.forName("org.sqlite.JDBC");' do? What is the purpose of 'Class.forName("MY_JDBC_DRIVER")'? Loading JDBC driver

【讨论】:

换句话说,它允许您使用 Driver 类而无需显式导入您的类。这使您无需在类路径中包含 Oracle 驱动程序即可构建项目。 应该注意,虽然在“传统方式”中你会调用 Class.forName() 而不捕获对返回的 driverClass 的引用,所以乍一看它似乎是一个无操作操作 这是因为 JDBC 驱动程序应该有一个静态初始化程序,该初始化程序将驱动程序注册到 DriverManager。使用 Class.forName() 时,会执行此初始化程序并注册驱动程序。从 JDBC 4.0 开始,DriverManager 本身使用 ServiceLoader 在类路径中查找驱动程序。 @MattBall,关于 JDBC 4.0 之前的版本,获取对驱动程序的引用或调用该驱动程序类的静态函数将已经自动加载驱动程序类。那么为什么我们必须手动执行Class.forName("etc.driver") 呢? @Pacerier 假设不正确。 JDBC 不知道您要加载哪个驱动程序,因此 JDBC(与驱动程序无关)中没有任何东西知道引用驱动程序类。所以你需要 something 来触发类加载。我想静态方法可以代替Class.forName(...)【参考方案2】:

它注册驱动程序;某种形式:

public class SomeDriver implements Driver 
  static 
    try 
      DriverManager.registerDriver(new SomeDriver());
     catch (SQLException e) 
      // TODO Auto-generated catch block
    
  

  //etc: implemented methods

【讨论】:

【参考方案3】:

来自Java JDBC tutorial:

在以前的 JDBC 版本中,要获得连接,首先必须通过调用方法 Class.forName 来初始化 JDBC 驱动程序。 在您的类路径中找到的任何 JDBC 4.0 驱动程序都会自动加载。 (但是,您必须使用 Class.forName 方法手动加载 JDBC 4.0 之前的所有驱动程序。)

因此,如果您将 Oracle 11g (11.1) 驱动程序与 Java 1.6 一起使用,则无需调用 Class.forName。否则,您需要调用它来初始化驱动程序。

【讨论】:

@Jonathan“使用 Class.forName 方法手动加载 JDBC 4.0 之前的任何驱动程序”是什么意思,您能解释一下吗? Class.forName 调用强制类加载器加载给定的类。这是教程中描述的手动加载步骤。 @Jonathan 所以这就是为什么我的连接在没有class.forName(); 的情况下仍然有效:)【参考方案4】:

在 Java 6 之前,DriverManager 类不会知道您想使用哪个 JDBC 驱动程序。 Class.forName("...") 是一种预加载驱动程序类的方法。

如果您使用的是 Java 6,则不再需要这样做。

【讨论】:

是的,需要使用:OracleDataSource now docs.oracle.com/cd/B28359_01/java.111/b31224/urls.htm#i1070726 它自己生成 url:final OracleDataSource ds = new OracleDataSource(); ds.setDriverType("瘦"); ds.setServerName(主机名); ds.setPortNumber(端口); //ds.setDatabaseName(dbName); ds.setServiceName(dbName);连接 = ds.getConnection(user, pwd);【参考方案5】:

此命令加载可用于 DriverManager 实例的 Oracle jdbc 驱动程序类。加载类后,系统可以使用它连接到 Oracle。作为替代方案,您可以使用 DriverManager 的 registerDriver 方法并将其与您需要的 JDBC 驱动程序实例一起传递。

【讨论】:

【参考方案6】:

use the jdbc.drivers System property 的替代方法是在您启动 JVM 时在命令行上指定所需的驱动程序。

【讨论】:

【参考方案7】:

使用 oracle.jdbc.OracleDriver,而不是 oracle.jdbc.driver.OracleDriver。如果驱动jar文件在“WEB-INF\lib”目录下,则无需注册,如果您使用的是Tomcat。将其保存为 test.jsp 并将其放在您的 web 目录中,然后在 Tomcat 管理器中重新部署您的 web 应用程序文件夹:

<%@ page import="java.sql.*" %>

<html>
<HEAD>
<TITLE>Simple JSP Oracle Test</TITLE>
</HEAD><BODY>
<%
Connection conn = null;
try 
    Class.forName("oracle.jdbc.OracleDriver");
    conn = DriverManager.getConnection("jdbc:oracle:thin:@XXX.XXX.XXX.XXX:XXXX:dbName", "user", "password");
    Statement stmt = conn.createStatement();
    out.println("Connection established!");

catch (Exception ex)

    out.println("Exception: " + ex.getMessage() + "");


finally

    if (conn != null) 
        try 
            conn.close();   
        
        catch (Exception ignored) 
            // ignore
        
    


%>

【讨论】:

以上是关于连接数据库时 Class.forName("oracle.jdbc.driver.OracleDriver") 的实际用途是啥?的主要内容,如果未能解决你的问题,请参考以下文章

由JDBC而来的对Class.forName()用法发散

Class.forName(Driver.class)

JAVA导出JAR文件后不能连接数据库了 Class.forName(driver).newInstance();空指针异常

图模.数据库连接测试.简单操作

Class.forName(“com.mysql.jdbc.Driver”)错误jsp [重复]

在 Web 应用程序中通过 JDBC 连接到数据库时,何时需要 Class.forName?