一尘不染

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

mysql

根据本教程Class.forNameJDBC
4.0+驱动程序不再需要调用。我成功地遵循了示例中的方法(只是调用DriverManager.getConnection)使用MySQL的独立程序,但是当我尝试从属于在Tomcat
7上运行的Web应用程序的类的类连接到完全相同的数据库时,它不会工作 相反,我有一个No suitable driver found例外。

mysql-connector-java-5.1.18-bin.jar文件位于tomcat\webapps\DatabaseProject\WEB- INF\lib,我进行了三遍检查,但无法正常工作,因此我开始尝试。我添加了一个呼叫,Class.forName并且成功了。那是唯一改变的事情。

无论如何,我的问题是,有人知道为什么这样做有效吗?我唯一的理论是我也hsqldb.jar参与tomcat\lib另一个项目,也许驾驶员莫名其妙地感到困惑?但是我给人的印象是,DriverManager应该能够自动告诉要使用哪个驱动程序,所以这不应该是一个问题…无论如何,如果有人可以向我介绍这里发生的事情,我将非常感激它。


阅读 329

收藏
2020-05-17

共1个答案

一尘不染

JDBC4驱动程序包含一个文件:

META-INF/services/java.sql.Driver

在使用ServiceProvider机制向JVM注册Driver实现的jar中(请参阅javadocs以获取java.util.ServiceLoader)。这就是为什么Class.forName不再需要。

我的猜测是这是一个类加载器问题。在ServiceLoaderjavadoc中提到:

该提供程序必须可以从最初查询以查找配置文件的同一类加载程序进行访问;请注意,这不一定是实际从中加载文件的类加载器。

我会尝试将驱动程序放在tomcat\lib目录而不是Web应用程序目录中,以查看是否有所不同(不同的类加载器?)。

如果通过ide启动Web应用程序并设置断点,则一旦达到断点,就可以使用“求值表达式”功能执行:ServiceLoader.load(Driver.class)。这将为您提供一ServiceLoader堂课,您可以查看一下已注册的驱动程序。您可以检查mysql驱动程序是否存在,在列表中的位置等等,这可能有助于在此处弄清楚行为。

2020-05-17