在 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 工作)