关于java:JDBC是如何知道去哪里寻找驱动类的?

How does JDBC know where to look for driver class?

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

示例:

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

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

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

开头

jdbc:derby:...

我期待的是这样的:

jdbc:ConcreteDriverClassForInit

如您所见,我缺少在类加载器中加载的类与该类的连接字符串调用之间的链接。

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

即使我尝试某事。这样,JDBC还是知道的,怎么办:

1
2
3
4
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");

但是为什么呢?
感谢您的帮助!


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

1
2
3
static {
    EmbeddedDriver.boot();
}

在这里查看启动方法的代码,你会看到协议注册在哪里:

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

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

1
String PROTOCOL ="jdbc:derby:";

这是所有 JDBC 驱动程序都遵循的通用模式,我不是特别喜欢这个驱动程序的代码,如果你想要一个更简洁的示例,请查看 SQLite 驱动程序,更直接的实现方式:

1
2
3
4
5
6
7
8
static {
    try {
        DriverManager.registerDriver(new JDBC());
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
}

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


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

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

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

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

1
DriverManager.getConnection("yourUrlHere")

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