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

Posted

技术标签:

【中文标题】在 Web 应用程序中通过 JDBC 连接到数据库时,何时需要 Class.forName?【英文标题】:When is Class.forName needed when connecting to a database via JDBC in a web app? 【发布时间】:2011-11-09 22:47:29 【问题描述】:

根据this tutorial,JDBC 4.0+ 驱动程序不再需要调用Class.forName。对于使用 mysql 的独立程序,我成功地按照示例中的方法(仅调用 DriverManager.getConnection),但是当我尝试从一个类连接到完全相同的数据库时,该类是在 Tomcat 7 上运行的 Web 应用程序的一部分,它行不通;相反,我得到了No suitable driver found 异常。

mysql-connector-java-5.1.18-bin.jar 文件在tomcat\webapps\DatabaseProject\WEB-INF\lib 中,我检查了三次,但它不起作用,所以我开始尝试。我添加了对Class.forName 的调用,它起作用了。这是唯一改变的事情。

无论如何,我的问题是,有人知道为什么会这样或者这里发生了什么吗?我唯一的理论是我在tomcat\lib 中也有hsqldb.jar 用于另一个项目,也许司机不知何故感到困惑?但我的印象是 DriverManager 应该能够自动判断要使用哪个驱动程序,所以这不应该是一个问题......无论如何,如果有人能告诉我这里发生了什么,我真的很感激它。

【问题讨论】:

【参考方案1】:

JDBC4 驱动包含一个文件:

META-INF/services/java.sql.Driver

在使用 ServiceProvider 机制向 JVM 注册驱动程序实现的 jar 中(参见 java.util.ServiceLoader 的 javadocs)。这就是不再需要Class.forName 的原因。

我的猜测是这是一个类加载器问题。 ServiceLoader javadoc 提到:

提供程序必须可以从与之前相同的类加载器访问 最初查询定位配置文件;请注意,这是 不一定是文件实际所在的类加载器 已加载。

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

如果您通过 ide 启动 Web 应用并设置断点,一旦您遇到断点,您可以使用“评估表达式”功能来执行:ServiceLoader.load(Driver.class)。这将为您提供一个ServiceLoader 类,您可以查看该类以查看哪些驱动程序已注册。您可以检查 mysql 驱动程序是否存在,它在列表中的位置等,这可能有助于找出此处的行为。

【讨论】:

我刚看到这个,非常感谢您的回答!对此,我真的非常感激。我稍后会试试这个,看看它是否能帮助我查明问题。

以上是关于在 Web 应用程序中通过 JDBC 连接到数据库时,何时需要 Class.forName?的主要内容,如果未能解决你的问题,请参考以下文章

在同一局域网中通过 JDBC 连接到 Postgres 服务器时出现 PSQLException(PGAdmin 工作)

在eclipse中通过jdbc连接DB2数据库

在 C 中通过 HTTP 连接到网站

在 Java 中通过 SSH 隧道连接到 Mongo 数据库

在 Android 中通过 XAMPP 连接到 MYSQL

在 Spring Boot 2、Hibernate、PostgreSQL 中通过 JDBC 语句执行 DDL 时出错