Java 为什么我们在连接数据库时使用 Class.forName(“oracle.jdbc.driver.OracleDriver”)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20078586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why we use Class.forName(“oracle.jdbc.driver.OracleDriver”) while connecting to a database?
提问by vidyashi
What is the actual use of Class.forName("oracle.jdbc.driver.OracleDriver")
while connecting to a database? Why cant we just import the same class, instead why we are loading it.
Class.forName("oracle.jdbc.driver.OracleDriver")
连接到数据库时的实际用途是什么?为什么我们不能只导入同一个类,而是为什么要加载它。
回答by hatesms
It`s a legacy way to do so. Importing class you will have extra dependency
这是这样做的传统方式。导入类你会有额外的依赖
From The Java Tutorial:
来自 Java 教程:
In previous versions of JDBC, to obtain a connection, you first had to initialize your JDBC driver by calling the method Class.forName. This methods required an object of type java.sql.Driver. Each JDBC driver contains one or more classes that implements the interface java.sql.Driver.
...
Any JDBC 4.0 drivers that are found in your class path are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)
在以前的 JDBC 版本中,要获得连接,首先必须通过调用 Class.forName 方法来初始化 JDBC 驱动程序。此方法需要一个 java.sql.Driver 类型的对象。每个 JDBC 驱动程序都包含一个或多个实现接口 java.sql.Driver 的类。
...
在您的类路径中找到的任何 JDBC 4.0 驱动程序都会自动加载。(但是,您必须使用 Class.forName 方法手动加载 JDBC 4.0 之前的任何驱动程序。)
回答by Mike Clark
A couple reasons to use Class.forName("")
instead of just referencing the class directly:
使用Class.forName("")
而不是直接引用类的几个原因:
Using
Class.forName("")
gives you more obvious control over where exactly the first attempt to load the specified class will be made in your code. This makes it more obvious where the code will fail (throw an exception) if that class is not present in the classpath when that code runs.If you simply import the class and then reference it in your code, it becomes slightly less obvious where the code will throw an exception if the class is not present.
Also, using
Class.forName("")
is a way to get around potential compile-time restrictions. If, for example, the person compiling the code does not (for, let's say, licensing or intellectual property reasons) have access to the class oracle.jdbc.driver.OracleDriver, they may find it easier to compile code which references the class byClass.forName("")
rather than directly.If you do not need to use any methods, fields, or inner classes of the specified class, then
Class.forName("")
may be the clearest way to express that the only thing desired is to load the class (and have its static initializers run), and nothing else.
使用
Class.forName("")
使您可以更明显地控制在代码中首次尝试加载指定类的确切位置。如果该代码运行时该类不存在于类路径中,则这使得代码将在何处失败(抛出异常)变得更加明显。如果您只是简单地导入该类,然后在您的代码中引用它,那么如果该类不存在,代码将抛出异常的地方就变得不那么明显了。
此外,使用
Class.forName("")
是一种绕过潜在编译时限制的方法。例如,如果编译代码的人没有(例如,由于许可或知识产权原因)访问类 oracle.jdbc.driver.OracleDriver,他们可能会发现编译引用该类的代码更容易Class.forName("")
而不是直接。如果您不需要使用指定类的任何方法、字段或内部类,那么
Class.forName("")
可能是表达唯一需要的是加载类(并运行其静态初始值设定项)而不是其他任何事情的最清楚方法.
I don't think Class.forName exhibits any different functional behavior than referencing the class directly. It uses the calling class' classloader by default, which should be the same classloader that is used when referencing the class directly. There are some overloads to Class.forName("") that let you customize the class loading behavior a bit more.
我认为 Class.forName 与直接引用类没有任何不同的功能行为。它默认使用调用类的类加载器,它应该与直接引用类时使用的类加载器相同。Class.forName("") 有一些重载,可以让您更多地自定义类加载行为。
回答by Mark Rotteveel
The basic idea behind using Class.forName()
is to load a JDBC driver implementation. A (normal) JDBC driver must contain a static initializer that registers an instance of the driver implementation with java.sql.DriverManager
:
using 背后的基本思想Class.forName()
是加载 JDBC 驱动程序实现。(普通)JDBC 驱动程序必须包含一个静态初始值设定项,用于注册驱动程序实现的实例java.sql.DriverManager
:
JDBC drivers must implement the
Driver
interface, and the implementation must contain a static initializer that will be called when the driver is loaded. This initializer registers a new instance of itself with theDriverManager
JDBC 驱动程序必须实现该
Driver
接口,并且该实现必须包含一个静态初始化程序,该初始化程序将在加载驱动程序时调用。这个初始值设定项注册了一个自己的新实例DriverManager
(from JDBC 4.1, section 9.2)
(来自 JDBC 4.1,第 9.2 节)
Since JDBC 4.0 however there is a new way to register drivers: the jar of a JDBC driver needs to include a file /META-INF/services/java.sql.Driver
which contains the name(s) of the java.sql.Driver
implementations in that jar. When you create a connection using the DriverManager
, it will use java.util.ServiceLoader
to enumerate all /META-INF/services/java.sql.Driver
files in the classpath and load all drivers so they get registered.
但是,从 JDBC 4.0 开始,有一种注册驱动程序的新方法:JDBC 驱动程序的 jar 需要包含一个文件/META-INF/services/java.sql.Driver
,该文件包含该java.sql.Driver
jar 中实现的名称。当您使用 来创建连接时DriverManager
,它将java.util.ServiceLoader
用于枚举/META-INF/services/java.sql.Driver
类路径中的所有文件并加载所有驱动程序以便它们被注册。
The
DriverManager.getConnection
method has been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the fileMETA-INF/services/java.sql.Driver
. This file contains the name of the JDBC driver's implementation ofjava.sql.Driver
.
该
DriverManager.getConnection
方法已得到增强以支持 Java Standard Edition Service Provider 机制。JDBC 4.0 驱动程序必须包含文件META-INF/services/java.sql.Driver
. 此文件包含 JDBC 驱动程序实现的名称java.sql.Driver
。
(from JDBC 4.1, section 9.2.1)
(来自 JDBC 4.1,第 9.2.1 节)
The reasons drivers are loaded this way, is that it allows you to decouple an application from the driver (and database) it uses. This means that you can write, compile and even distribute an application without any drivers, you only need to use the interfaces provided in the java.sql
(and javax.sql
) package - which is part of Java - without needing to access the implementation directly.
驱动程序以这种方式加载的原因是它允许您将应用程序与其使用的驱动程序(和数据库)分离。这意味着您可以在没有任何驱动程序的情况下编写、编译甚至分发应用程序,您只需要使用java.sql
(and javax.sql
) 包中提供的接口——它是 Java 的一部分——而无需直接访问实现。
The user of the application then adds a valid JDBC driver to the classpath (and configuring things like a connection string) so the application can actually to connect to a database. Before JDBC 4.0, the user would have to specify the driver name so that the application could load it using Class.forName
, with a JDBC 4.0 compliant driver and Java 6 or higher this discovery is automatic.
然后,应用程序的用户将有效的 JDBC 驱动程序添加到类路径(并配置诸如连接字符串之类的内容),以便应用程序实际上可以连接到数据库。在 JDBC 4.0 之前,用户必须指定驱动程序名称,以便应用程序可以使用 加载它,使用Class.forName
符合 JDBC 4.0 的驱动程序和 Java 6 或更高版本,此发现是自动的。
When you load a driver literally with Class.forName("oracle.jdbc.driver.OracleDriver")
it might feel like overkill, but if you keep in mind that it could also be a string pulled from a config file (or from user input) you might start to understand why it is so powerful.
当您从字面上加载驱动程序时,Class.forName("oracle.jdbc.driver.OracleDriver")
它可能会让人觉得有点矫枉过正,但如果您记住它也可能是从配置文件(或从用户输入)中提取的字符串,您可能会开始理解为什么它如此强大。
Of course this driver independence is not 100%, especially not if your application uses vendor specific SQL. But the theory is that your application can be database independent. JDBC also provides some additional mechanisms to address this, eg JDBC escapes to provide a common syntax that the driver translates to the specific syntax, and DatabaseMetaData
which allows you to discover features, reserved words etc which allow you to create or generate compatible queries.
当然,这种驱动程序独立性不是 100%,尤其是如果您的应用程序使用供应商特定的 SQL。但理论上您的应用程序可以独立于数据库。JDBC 还提供了一些额外的机制来解决这个问题,例如 JDBC 转义以提供驱动程序转换为特定语法的通用语法,并DatabaseMetaData
允许您发现允许您创建或生成兼容查询的功能、保留字等。
回答by Krishan
Class.forName(“oracle.jdbc.driver.OracleDriver”) takes the class name as a string argument and loads it into memory. Second way of loading a class is to simply creating an instance of it using new
. Disadvantage of second method is the newly created instance will be of no use if you don't need it.
Class.forName(“oracle.jdbc.driver.OracleDriver”) 将类名作为字符串参数加载到内存中。加载类的第二种方法是简单地使用new
. 第二种方法的缺点是新创建的实例如果你不需要它就没有用。
There is a nice tutorial explains JDBC connection basics.
有一个很好的教程解释了JDBC 连接基础知识。
回答by Shiva
Sometimes it is required to load a class during the run time. i.e, any class can be loaded into the memory location dynamically while executing the java application. The Class.forName
is used to load any given class (within double quotes as String) at run time. For example, when we use IDE, we see there will be a GUI builder which allows us to drag and drop the buttons, text fields, etc. This drag and drop mechanism internally requires certain classes to be loaded at run time.
有时需要在运行时加载一个类。即,任何类都可以在执行 java 应用程序时动态加载到内存位置。将Class.forName
用于加载的任何给定的类在运行时(双引号为字符串内)。例如,当我们使用 IDE 时,我们会看到有一个 GUI 构建器,它允许我们拖放按钮、文本字段等。这种拖放机制在内部需要在运行时加载某些类。
In the Class.forName (sun.jdbc.odbc.JdbcOdbcDriver
), the Class belongs to the package java.lang.Class
and the forName()
is a static method of the java.lang.Class
. The JDBC Drivers (String) will be loaded into the class dynamically at run time and forName method contains static block which creates the Driver class object and register with the DriverManager
Service automatically. Since the forName()
is static, we call it using the class name (Class).
在 Class.forName( sun.jdbc.odbc.JdbcOdbcDriver
) 中,Class 属于包java.lang.Class
,forName()
是java.lang.Class
. JDBC 驱动程序(字符串)将在运行时动态加载到类中,forName 方法包含静态块,它创建驱动程序类对象并DriverManager
自动向服务注册。由于forName()
是静态的,我们使用类名(Class)来调用它。
回答by Himanshu Bhandari
When we want to execute static block of a class, without creating its object then we can use class.forName()
. Most of the work that Driver
class do, exists in its static block.
当我们想执行一个类的静态块而不创建它的对象时,我们可以使用class.forName()
. Driver
该类所做的大部分工作都存在于其静态块中。
Now what we require in our JDBC connectivity is to get the driver registered with DriverManager
and to obtain connections with it, so this can be achieved simply by getting static block executed and there is no requirement to create object of that class. This approach will give a better performance.
现在我们在 JDBC 连接中需要的是让驱动程序注册DriverManager
并获得与它的连接,所以这可以通过执行静态块来实现,不需要创建该类的对象。这种方法将提供更好的性能。
回答by Wajid Ali
This is used for to open a class or in other words invoke it via its name from string format.
For example:
这用于打开一个类,或者换句话说,通过字符串格式的名称调用它。
例如:
Class.forName("com.android.example.MainClass");
And it will start the class inside the package com/android/example/MainClass.java
它将在包 com/android/example/MainClass.java 中启动类