JDBC如何知道在哪里查找驱动程序类?

时间:2022-11-16 08:08:34

I am wondering how JDBC knows which database driver class it should use.

我想知道JDBC如何知道它应该使用哪个数据库驱动程序类。

Example:

例:

Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Connection verbindung = DriverManager.getConnection("jdbc:derby:d:/memory/onlineshop;create=true");

The first line takes Care, that a driver (EmbeddedDriver) will be loaded into to class loader (and so be available, e.g. for using with reflections, right?).

第一行需要注意,驱动程序(EmbeddedDriver)将加载到类加载器(因此可用,例如用于反射,对吗?)。

So, the next line is my connection string. It starts with:

所以,下一行是我的连接字符串。它始于:

jdbc:derby:...

JDBC:德比:...

I expected something like this instead:

我期待这样的事情:

jdbc:ConcreteDriverClassForInit

JDBC:ConcreteDriverClassForInit

As you can see i am missing a link between the class loaded in the class loader and the connection string call of that class.

正如您所看到的,我错过了类加载器中加载的类与该类的连接字符串调用之间的链接。

I searched in the derby archive for a class named "Derby.Class" - but there is no such class.

我在derby存档中搜索了一个名为“Derby.Class”的类 - 但是没有这样的类。

Even when I try sth. like this, JDBC still knows, what to do:

即使我尝试了......像这样,JDBC仍然知道,该怎么做:

Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
Class.forName("org.something.anyotherDBDriver1");
Class.forName("org.something.anyotherDBDriver2");
Connection verbindung = DriverManager.getConnection("jdbc:derby:d:/memory/onlineshop;create=true");

But why? Thanks for your help!

但为什么?谢谢你的帮助!

2 个解决方案

#1


4  

That EmbeddedDriver class has a static block executed when you load the class that adds an handler for the specific JDBC type:

当您加载为特定JDBC类型添加处理程序的类时,EmbeddedDriver类会执行一个静态块:

static {
    EmbeddedDriver.boot();
}

Check the code of the boot method here, and you'll see where the protocol is registered:

在这里检查引导方法的代码,您将看到协议的注册位置:

new JDBCBoot().boot(Attribute.PROTOCOL, ps);

That specific string is located in org.apache.derby.iapi.reference:

该特定字符串位于org.apache.derby.iapi.reference中:

String PROTOCOL = "jdbc:derby:";

That's a common pattern that is followed by all JDBC drivers, i don't particularly like the code of this driver, if you want a cleaner example look at the SQLite driver, way more straightforward implementation:

这是所有JDBC驱动程序遵循的常见模式,我不是特别喜欢这个驱动程序的代码,如果你想要一个更清晰的例子来看看SQLite驱动程序,那么实现更直接:

static {
    try {
        DriverManager.registerDriver(new JDBC());
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
}

org.sqlite.JDBC will register itself to the java.sql.DriverManager that will invoke JDBC.isValidURL(String url) to know if this class is a valid driver for a specific JDBC url, the SQLite driver will return true only if the url contains the PREFIX jdbc:sqlite:.

org.sqlite.JDBC将自己注册到将调用JDBC.isValidURL(String url)的java.sql.DriverManager,以了解此类是否是特定JDBC url的有效驱动程序,SQLite驱动程序仅在URL时才返回true包含PREFIX jdbc:sqlite:。

#2


1  

In previous versions of JDBC, to obtain a connection, you first need to load your JDBC driver by calling the method Class.forName().

在以前的JDBC版本中,要获得连接,首先需要通过调用Class.forName()方法来加载JDBC驱动程序。

Currently any JDBC 4.0 drivers that are found in your class path are automatically loaded. So, there is not even the need for Class.forName().

目前,在类路径中找到的任何JDBC 4.0驱动程序都会自动加载。因此,甚至不需要Class.forName()。

The gist of it is to be found in the documentation for java.sql.Driver and java.sql.DriverManager.

它的要点可以在java.sql.Driver和java.sql.DriverManager的文档中找到。

Basically, starting with JDBC 4, all you have to do is create a META-INF/services/java.sql.Driver file for your SQL driver implementation and the JRE will load it automatically. Which means that you can directly try and do:

基本上,从JDBC 4开始,您所要做的就是为SQL驱动程序实现创建META-INF / services / java.sql.Driver文件,JRE将自动加载它。这意味着您可以直接尝试:

DriverManager.getConnection("yourUrlHere")

If one driver recognizes the URL, it will be used automatically.

如果一个驱动程序识别该URL,它将自动使用。

#1


4  

That EmbeddedDriver class has a static block executed when you load the class that adds an handler for the specific JDBC type:

当您加载为特定JDBC类型添加处理程序的类时,EmbeddedDriver类会执行一个静态块:

static {
    EmbeddedDriver.boot();
}

Check the code of the boot method here, and you'll see where the protocol is registered:

在这里检查引导方法的代码,您将看到协议的注册位置:

new JDBCBoot().boot(Attribute.PROTOCOL, ps);

That specific string is located in org.apache.derby.iapi.reference:

该特定字符串位于org.apache.derby.iapi.reference中:

String PROTOCOL = "jdbc:derby:";

That's a common pattern that is followed by all JDBC drivers, i don't particularly like the code of this driver, if you want a cleaner example look at the SQLite driver, way more straightforward implementation:

这是所有JDBC驱动程序遵循的常见模式,我不是特别喜欢这个驱动程序的代码,如果你想要一个更清晰的例子来看看SQLite驱动程序,那么实现更直接:

static {
    try {
        DriverManager.registerDriver(new JDBC());
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
}

org.sqlite.JDBC will register itself to the java.sql.DriverManager that will invoke JDBC.isValidURL(String url) to know if this class is a valid driver for a specific JDBC url, the SQLite driver will return true only if the url contains the PREFIX jdbc:sqlite:.

org.sqlite.JDBC将自己注册到将调用JDBC.isValidURL(String url)的java.sql.DriverManager,以了解此类是否是特定JDBC url的有效驱动程序,SQLite驱动程序仅在URL时才返回true包含PREFIX jdbc:sqlite:。

#2


1  

In previous versions of JDBC, to obtain a connection, you first need to load your JDBC driver by calling the method Class.forName().

在以前的JDBC版本中,要获得连接,首先需要通过调用Class.forName()方法来加载JDBC驱动程序。

Currently any JDBC 4.0 drivers that are found in your class path are automatically loaded. So, there is not even the need for Class.forName().

目前,在类路径中找到的任何JDBC 4.0驱动程序都会自动加载。因此,甚至不需要Class.forName()。

The gist of it is to be found in the documentation for java.sql.Driver and java.sql.DriverManager.

它的要点可以在java.sql.Driver和java.sql.DriverManager的文档中找到。

Basically, starting with JDBC 4, all you have to do is create a META-INF/services/java.sql.Driver file for your SQL driver implementation and the JRE will load it automatically. Which means that you can directly try and do:

基本上,从JDBC 4开始,您所要做的就是为SQL驱动程序实现创建META-INF / services / java.sql.Driver文件,JRE将自动加载它。这意味着您可以直接尝试:

DriverManager.getConnection("yourUrlHere")

If one driver recognizes the URL, it will be used automatically.

如果一个驱动程序识别该URL,它将自动使用。