MySQL驱动程序通常以jar包形式存在,例如mysql-connector-java-8.0.33.jar。它的存放位置直接决定Java程序能否通过DriverManager找到并加载驱动。不同项目结构下,这个jar包需要放在不同位置,而且在JDBC 4.0之后驱动加载机制也发生了变化。下面从几个常见环境分别说明。

普通Java项目中的驱动存放位置
在没有构建工具的传统Java项目中,通常会在工程根目录创建一个名为lib的文件夹,专门存放第三方jar包。MySQL驱动jar应当复制到该目录下,例如lib/mysql-connector-java-8.0.33.jar。仅仅把文件放进去还不够,还需要在编译和运行时将这个jar加入classpath。以命令行编译运行为例,假设Main.java位于src目录且已经编译到bin目录,可以使用以下命令:
java -cp "bin;lib/mysql-connector-java-8.0.33.jar" com.example.Main
在Linux或macOS下,classpath分隔符为冒号,命令变为:
java -cp "bin:lib/mysql-connector-java-8.0.33.jar" com.example.Main
类加载器只会在classpath指定的路径中搜索类,如果驱动jar不在classpath中,运行时就会抛出ClassNotFoundException。在IDE中开发时,通常需要右键jar包选择添加到构建路径,或通过项目结构设置将其标记为库。注意不要将驱动jar放入JRE的lib/ext目录,Java 9之后扩展机制已被移除,而且这种做法很容易导致不同应用之间的版本冲突。
另外,如果项目使用Java模块化系统,还需要在module-info.java中通过requires声明对驱动模块的依赖,否则即使jar在模块路径中也可能无法访问。普通非模块化项目则不受此限制。
Maven和Gradle项目中的驱动依赖位置
使用Maven或Gradle构建的项目不需要手动下载和存放驱动jar。只需在pom.xml或build.gradle中声明依赖,构建工具会自动解析并下载到本地仓库。Maven的默认本地仓库位于用户目录下的.m2/repository,具体路径为~/.m2/repository/mysql/mysql-connector-java/8.0.33/mysql-connector-java-8.0.33.jar。在Windows系统中,该路径通常为C:\Users\用户名\.m2\repository\mysql\mysql-connector-java\8.0.33\,注意路径中使用反斜杠分隔,用户目录名根据实际账户不同而变化。下面是Maven的依赖片段:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>Gradle的缓存位置在~/.gradle/caches/modules-2/files-2.1/mysql/mysql-connector-java/8.0.33/目录下。这些由工具管理的依赖不需要开发者关心具体存放路径,但了解实际位置有助于排查依赖冲突或清理缓存。如果本地仓库中的驱动jar损坏或版本混乱,可以删除对应目录后重新执行构建命令。
对于MySQL 8.x版本,驱动类名已经变更为com.mysql.cj.jdbc.Driver,而5.1及更早版本使用com.mysql.jdbc.Driver。在构建文件中声明版本时,建议保持驱动版本与数据库服务器版本大版本一致,以避免因协议不兼容导致连接失败。
Web容器中的驱动存放位置
部署在Tomcat等Servlet容器中的传统Web应用,驱动jar有两种放置方式。推荐的做法是将驱动放入应用自己的WEB-INF/lib目录中,例如webapp/WEB-INF/lib/mysql-connector-java-8.0.33.jar。这样每个应用携带自己的驱动版本,互不影响,也方便随应用一起打包和迁移。目录结构可以用下面的层次表示:
webapp
WEB-INF
lib
mysql-connector-java-8.0.33.jar
classes
web.xml
index.jsp另一种方式是将驱动jar放入Tomcat安装目录的lib文件夹中,例如tomcat/lib/mysql-connector-java-8.0.33.jar。这样Tomcat的公共类加载器会加载该驱动,所有部署在该容器中的应用都能使用。这种方式适合多个应用共享同一个数据库驱动,但升级驱动时会影响全部应用,而且如果应用自身WEB-INF/lib中也放了一份不同版本的驱动,可能产生类加载冲突。
当使用JNDI数据源配置数据库连接时,如果数据源定义在Tomcat的context.xml或server.xml中,驱动必须放在Tomcat的lib目录下,因为数据源由Tomcat容器创建,需要容器级别的类加载器能够找到驱动类。如果数据源在应用内部定义,则驱动放在WEB-INF/lib即可。
驱动加载原理与常见错误排查
从JDBC 4.0开始,驱动jar包中会包含META-INF/services/java.sql.Driver文件,其中列出了实现Driver接口的类名。只要驱动jar位于classpath中,DriverManager在初始化时就会通过ServiceLoader机制自动加载并注册驱动,因此现代Java应用通常不需要显式调用Class.forName。但很多旧教程仍然保留Class.forName("com.mysql.cj.jdbc.Driver")这样的代码,这种写法不会出错,只是多余。
最常见的错误是ClassNotFoundException: com.mysql.cj.jdbc.Driver,出现这个异常基本可以断定驱动jar没有出现在运行时的classpath中,或者使用了错误的驱动类名。例如MySQL 5.1的驱动类名是com.mysql.jdbc.Driver,如果代码使用新类名而实际驱动是5.1版本,就会报这个错。另一个高频错误是No suitable driver found,通常是因为JDBC URL格式不对,比如写成了jdbc:mysql://localhost:3306/test但缺少正确的协议前缀,或者驱动根本没有注册。
排查时可以打印Java进程的classpath,确认驱动jar的实际路径是否包含在内。可以在代码中输出系统属性java.class.path,或者在命令行使用以下命令查看:
System.out.println(System.getProperty("java.class.path"));如果发现路径中没有驱动jar,就需要检查IDE的构建配置、Maven依赖是否声明正确,或者Tomcat的lib目录是否存在该文件。同时要注意避免同一个jar被多个类加载器重复加载,尤其是当驱动同时出现在Tomcat的lib和应用的WEB-INF/lib中时,可能导致驱动注册混乱,应用获取到的连接行为异常。