【问题标题】:Cannot connect to MySQL on localhost using JDBC Driver [duplicate]无法使用 JDBC 驱动程序连接到本地主机上的 MySQL [重复]
【发布时间】:2018-10-10 01:27:09
【问题描述】:

我无法连接到在我自己的机器上运行的 MySQL 实例,但我对这种情况的了解不够,无法诊断问题。

public void readDataBase() throws Exception {
    Connection connection = null;
    Class.forName("com.mysql.jdbc.Driver");
   
    String url = "jdbc:mysql://localhost:3306/tmlschedule";
    
    try {

        connection = DriverManager.getConnection(url, "user", "pass");
   
    } catch (Exception e) {
        throw e;
    } finally {
        close();
    }
}

.getConnection() 的调用会引发以下堆栈跟踪:

Exception in thread "main"
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Could not create connection to database server.     at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)     at
com.mysql.jdbc.Util.getInstance(Util.java:386)  at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)  at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)   at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)   at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)   at
com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2570)
    at
com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2306)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:839)    at
com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)  at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)     at
com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:421)  at
com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:350)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)     at
java.sql.DriverManager.getConnection(DriverManager.java:247)    at
tmlSchedule.MySQLAccess.readDataBase(MySQLAccess.java:22)   at
tmlSchedule.TmlSchedule.main(TmlSchedule.java:9) Caused by:
java.lang.NullPointerException  at
com.mysql.jdbc.ConnectionImpl.getServerCharacterEncoding(ConnectionImpl.java:3281)
    at com.mysql.jdbc.MysqlIO.sendConnectionAttributes(MysqlIO.java:1940)
    at
com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1866)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1252)    at
com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2488)
    at
com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2521)
    ... 14 more

到目前为止我做了什么:

  • 确认表名、用户名和密码。我可以使用所有这些变量登录到 mysql shell (mysql -u user -p) 并运行 select & insert 命令。
  • 将用户名和密码替换为 mysql 实例上 root 用户的登录详细信息。
  • 在 Eclipse 的 Java Build Path 菜单中引用 mysql-connector-java.jar
  • 通过用于 firewalld 的 GUI 将 mysql 添加为受信任的服务。
  • 在禁用防火墙的情况下运行代码 (sudo systemctl stop firewalld)。这没有任何区别。
  • 检查 mysql 是否正在侦听端口 3306。sudo netstat -tuplen 包括以下条目: tcp6 0 0 :::3306 :::* LISTEN 27 113879 7224/mysqld

任何帮助将不胜感激。

编辑:

我在试图弄清楚 MySQL 和驱动程序的版本控制时感到非常困惑。

$ zipgrep 'Bundle-Version' /usr/share/java/mysql-connector-java.jar 返回:

META-INF/MANIFEST.MF:Bundle-Version: 5.1.25`

$ mysql --version 返回:

mysql Ver 8.0.12 for Linux on x86_64 (MySQL Community Server - GPL)

这表明驱动程序已过期,但我通过列出的 yum 存储库 here 安装了 MySQL,我想它会为我提供与数据库匹配的驱动程序。我还尝试通过here 列出的 rpm 包安装 Connector/J 8.0,但我收到以下消息,这对我来说没有意义:

package mysql-connector-java-1:5.1.25-3.el7.noarch(较新 mysql-connector-java-8.0.12-1.el7.noarch) 已经安装了

【问题讨论】:

  • JDBC驱动版本和数据库版本一样吗?
  • 您是否能够连接到数据库,例如,从命令提示符处?
  • 问题在于带有字符编码的NullPointerException,如异常跟踪中所示。正如@prasad_ 指出的那样,可能是由于版本不匹配(请参阅stackoverflow.com/questions/46137173/…)。也可以尝试将字符编码附加到连接 url。
  • 这是什么? private Connection connection = null;

标签: java mysql jdbc


【解决方案1】:

由于多种原因,应用程序可能无法连接到数据库。其中之一是未使用正确的驱动程序软件(又名 JDBC 驱动程序)。

在这种情况下,验证使用与数据库服务器本身兼容的 jdbc 驱动程序版本解决了该问题。

可以从here 获得正确的驱动软件。

可以从命令提示符验证 MySQL 服务器版本:首先,启动 MySQL 客户端,然后使用命令 mysql&gt; select version();

【讨论】:

  • 我在原始问题中添加了更多内容,但由于某种原因,我的系统上安装了旧版本的 mysql-connector-java,并且 rpm 拒绝承认版本 8 是比第 5 版更新。我最终卸载 ($ sudo yum remove mysql-connector-java),然后显式重新安装 ($ sudo yum install mysql-connector-java-8.0.12-1.el7)。连同下面切诺基的回答,这解决了这个问题。
  • MySQL Server 版本和所需的 JDBC 驱动版本没有直接关系。
  • @garroad_ran 你真的不应该将 yum 用于 Java 依赖项。
【解决方案2】:

我看不到提供的代码到底发生了什么,但是,当您构建一个数据访问对象时,您可能需要考虑以这样一种方式构建它,即您的 Connection 是您的类的变量,而不是类的方法。

此外,默认情况下,mysql 数据库通常会期望安全连接。要删除此默认值,请查看 url 变量。

public class DataAccessExample {

private Connection connection;
private final String driverClass = "com.mysql.jdbc.Driver";
private final String url = "jdbc:mysql://localhost:3306/tmlschedule?autoReconnect=true&useSSL=false";
private final String userName = "YOUR USERNAME";
private final String password = "YOUR PASSWORD";

//Consider calling this openConnection();
public void readDataBase() throws ClassNotFoundException, SQLException {
    Class.forName(driverClass);
    connection = DriverManager.getConnection(url, userName, password);
}

//Then have a close connection, this will make your life easier in the future
public void closeConnection() throws SQLException {
    if (connection != null) {
        connection.close();
    }
}

}

要使用此代码:

public static void main(String[] args) {
    DataAccessExample d = new DataAccessExample();

    try {
        d.readDataBase();
        d.closeConnection();
    } catch (ClassNotFoundException | SQLException ex) {
        Logger.getLogger(DataAccessExample.class.getName()).log(Level.SEVERE, null, ex);
    }
}

最后,确保您的数据库名称拼写正确,并且您的用户名和密码正确。

我希望这会有所帮助。

【讨论】:

  • 好东西。您指出的大部分内容是我压缩代码以使其尽可能小的结果,但我一定会听取您的建议。谢谢!
【解决方案3】:

如果你的mysql版本是8.x,很有可能是你的驱动版本太旧了,驱动类com.mysql.jdbc.Driver被弃用了,新的驱动类是com.mysql.cj.jdbc.Driver。驱动程序是通过 SPI 自动注册的,通常不需要手动加载驱动程序类。 以下代码来自official documentation

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

Connection conn = null;
...
try {
    conn =
       DriverManager.getConnection("jdbc:mysql://localhost/test?" +
                                   "user=minty&password=greatsqldb");

    // Do something with the Connection

    ...
} catch (SQLException ex) {
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());
    System.out.println("SQLState: " + ex.getSQLState());
    System.out.println("VendorError: " + ex.getErrorCode());
}

【讨论】:

  • 谢谢!只要我能够安装正确版本的驱动程序,您的建议就可以立即运行。我最终选择了 prasad_ 的答案,只是因为他先提示我版本不匹配,但您的回答也挽救了一天!
猜你喜欢
  • 2021-05-18
  • 2016-09-07
  • 1970-01-01
  • 2014-07-28
  • 2015-07-31
  • 2013-05-01
  • 2011-09-01
  • 1970-01-01
  • 2014-05-17
相关资源
最近更新 更多