You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

  1. 用root账号登录MySQL命令行:
mysql -u root -p
  1. 执行修改命令(把your_useryour_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

火山引擎 最新活动