Java Web应用连接MySQL的方法及认证协议错误解决
解决MySQL连接认证错误 + Java Web连接MySQL完整步骤
先搞定你遇到的认证错误
你碰到的com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server,本质原因很直白:你的MySQL服务器应该是8.0及以上版本,默认用caching_sha2_password这种新认证插件,但你用的mysql-connector-java-5.1.6是2012年的老版本,完全不兼容这个新认证方式。
给你两个解决方案,按需选择:
方案1:升级MySQL驱动到兼容版本(强烈推荐)
老驱动不仅不支持新认证,还有安全漏洞和功能缺失,升级是长远之计:
- 如果你用Maven,直接在
pom.xml替换依赖:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> <!-- 选最新8.x版本,至少要8.0以上 --> </dependency>
- 手动导入jar包的话,下载最新的
mysql-connector-java-8.x.x.jar,替换掉项目里的5.1.6版本,再在Eclipse中重新添加到Build Path。
⚠️ 注意:升级到8.x驱动后,JDBC连接的驱动类名要改成com.mysql.cj.jdbc.Driver,原来的com.mysql.jdbc.Driver已经被标记为过时了。
方案2:修改MySQL用户认证方式(仅临时测试用)
如果暂时不想升级驱动,可以把用户认证改回老的mysql_native_password:
- 用root账号登录MySQL命令行:
mysql -u root -p
- 执行修改命令(把
your_user和your_password换成你的实际信息):
ALTER USER 'your_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
改完就能用老驱动连接了,但还是建议尽快升级,毕竟老认证方式安全性更低。
Java Web应用连接MySQL的完整步骤
解决完错误后,咱们一步步配置项目:
1. 前期准备
- 确保MySQL服务器已启动,创建好目标数据库,给用户分配分配足够权限(比如
SELECT, INSERT, UPDATE等)。 - 下载对应版本的MySQL驱动:8.x对应MySQL 8.0+,5.x对应MySQL 5.x。
2. 在Eclipse数据源资源管理器配置连接
- 打开Eclipse,依次点击Window > Show View > Other > Data Source Explorer。
- 右键Database Connections > New,选择MySQL后点击Next。
- 若Driver列表没有合适选项,点击New Driver:
- 点击Add JARs,选择你下载的驱动jar包。
- 驱动类名:8.x填
com.mysql.cj.jdbc.Driver,5.x填com.mysql.jdbc.Driver。 - 点击OK回到连接配置页。
- 填写连接信息:
- Database:你的数据库名称。
- Host:本地服务器填
localhost,远程服务器填对应IP。 - Port:默认3306,修改过的话填对应端口。
- User name/Password:你的MySQL账号和密码。
- 8.x版本建议在URL后加时区参数:
jdbc:mysql://localhost:3306/your_db?serverTimezone=Asia/Shanghai,避免时区错误。
- 点击Test Connection,成功后保存连接即可。
3. 在Web项目中实现数据库连接
这里提供两种常用方式,推荐用连接池提升性能:
方式1:原生JDBC代码(适合小项目/测试)
先写一个数据库工具类:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DBUtil { private static final String URL = "jdbc:mysql://localhost:3306/your_db?serverTimezone=Asia/Shanghai"; private static final String USER = "your_user"; private static final String PASSWORD = "your_password"; private static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver"; static { try { Class.forName(DRIVER_CLASS); // 加载驱动 } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } // 统一关闭资源 public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) { try { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
然后在Servlet中调用:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = DBUtil.getConnection(); String sql = "SELECT * FROM your_table"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); // 处理查询结果 while (rs.next()) { System.out.println(rs.getString("column_name")); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(conn, pstmt, rs); } }
方式2:使用Tomcat JDBC连接池(推荐)
在项目WEB-INF下创建context.xml:
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="jdbc/YourDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/your_db?serverTimezone=Asia/Shanghai" username="your_user" password="your_password" maxTotal="100" maxIdle="30" maxWaitMillis="10000"/> </Context>
在web.xml中添加资源引用:
<resource-ref> <description>MySQL数据库连接</description> <res-ref-name>jdbc/YourDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
最后在Servlet中获取连接:
import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); DataSource ds = (DataSource) envCtx.lookup("jdbc/YourDB"); conn = ds.getConnection(); // 执行SQL操作逻辑和原生JDBC一致 } catch (Exception e) { e.printStackTrace(); } finally { // 关闭资源 try { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者chungus




