如何使用 JDBC 连接 docker 中运行的 MySQL 数据库?

问题描述 投票:0回答:1

在docker中通过JDBC连接MySQL时出现以下异常。

MySQL映射到docker中。端口信息在 PORTS 类别下的 docker 进程列表中显示如下

0.0.0.0:3306->3306/tcp, :::3306->3306/tcp

这是我使用它来连接数据库并向其中写入数据的示例代码。

public static void main(String[] args) {
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/sampledb", "root", "");
            Statement statement = connection.createStatement()) {
            ResultSet resultSet = statement.executeQuery("insert into demo values(1, \"A\")");
            /*Perform some operations*/
            resultSet.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

异常跟踪:

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:829)
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:449)
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:242)
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
    at Sample/com.test.Test.main(Test.java:14)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
    ... 6 more
Caused by: javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
    at java.base/sun.security.ssl.SSLSocketImpl.handleEOF(SSLSocketImpl.java:1719)
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1518)
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425)
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
    ... 11 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:489)
    ... 18 more

如何解决这个问题?

mysql docker jdbc mysql-connector java-17
1个回答
0
投票

尝试使用以下命令运行 docker 镜像:

docker run -it -p 33060:3306 --name hakky54-mysql -e MYSQL_ROOT_PASSWORD='secret' mysql

获取mysql的证书。在我的例子中,它是下面的 Snipper pem 文件,但它对于您的 mysql 实例可能有所不同。

subject=CN=MySQL_Server_8.3.0_Auto_Generated_Server_Certificate
issuer=CN=MySQL_Server_8.3.0_Auto_Generated_CA_Certificate
-----BEGIN CERTIFICATE-----
MIIDBTCCAe2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MTkwNwYDVQQDDDBNeVNR
TF9TZXJ2ZXJfOC4zLjBfQXV0b19HZW5lcmF0ZWRfQ0FfQ2VydGlmaWNhdGUwHhcN
MjQwMjIzMTUxMzA4WhcNMzQwMjIwMTUxMzA4WjA/MT0wOwYDVQQDDDRNeVNRTF9T
ZXJ2ZXJfOC4zLjBfQXV0b19HZW5lcmF0ZWRfU2VydmVyX0NlcnRpZmljYXRlMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1GLLGQD4ddF6bg6kG2W33ibS
XP+baKk9ztgW19U0l7Shc/5L/uMTz/+gV1vU9PZSIMvhbyS+rzmr0mIP+DUiz58O
0KwGJ2xRzNrKX8jtaWSoQOkQpEeifyTG4r8kcHxKx+ORgr3zIvLRCmNw/o0s/JCp
xlxc9LDbIOLb13uhnXAJlnCxkVw9so2oTJ7J7RlE0D7UvntvnLFbaAYaRmZPHAXC
DsbOH89Gg2lvxDnzMZ6VbBfCyPJEcGhpfCtKfGMz2z4EJz5LN2yMQtOs1QJcrEhN
jV5i7yqMFs6mAKhQVtOXC/Mrqy8KWavZwU+X/TsN0K0uy2YOs0bUrVSEsBBt/wID
AQABoxAwDjAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAw1AFXuE9G
jHNApMAOgG8L2sJFTU/0W6224OIItPScFj8Grm3O6Yma3Tb6Sha0GY1uupQOaVUC
xibv2seeDqvxstQeUeoAQtKpim5YA6tmkihcDXP1fYhjBQkWeWDWGssuaZ5BpD4Q
wg1L5OR66ZBOwcNqTC0+m36MyxQXngYO1akjJAEMqgGb/zdfTBUWi3y4gFdBZ5mD
Y87wiDGZuzPLYXTmWlFgv7ZLeGNb9bZST29DY4GFk0Fx3ezJ8LbE6l6oTy41wBcy
CQfs+JyA3ZByBkdB7Lrmvm0Wc8HZXoertq74LysyBITxMI4pwkO+w3D9GW33JUjN
2xXSIQT3QjnI
-----END CERTIFICATE-----
subject=CN=MySQL_Server_8.3.0_Auto_Generated_CA_Certificate
issuer=CN=MySQL_Server_8.3.0_Auto_Generated_CA_Certificate
-----BEGIN CERTIFICATE-----
MIIDBDCCAeygAwIBAgIBATANBgkqhkiG9w0BAQsFADA7MTkwNwYDVQQDDDBNeVNR
TF9TZXJ2ZXJfOC4zLjBfQXV0b19HZW5lcmF0ZWRfQ0FfQ2VydGlmaWNhdGUwHhcN
MjQwMjIzMTUxMzA4WhcNMzQwMjIwMTUxMzA4WjA7MTkwNwYDVQQDDDBNeVNRTF9T
ZXJ2ZXJfOC4zLjBfQXV0b19HZW5lcmF0ZWRfQ0FfQ2VydGlmaWNhdGUwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCR4QNDsdTiCrTCoShlJDiPi5DlgDjv
9d19hbGnaJUECHaREjjN6nOuGEAnWu0SN0ILiRZksvelBM5M0lggsprJZiOn/5YI
ogCMYA8QYcfTmzh28V71wWtpU1YRDC8dHuEpp+U3QiM38qV23gfYapXA8hzriDnW
f7YE0tBT8yJSpC++C5GpTzoBtQarH0TPGUWCLxMF2Rf+vE9bN3Z9M6+yXirzuoe9
PkrSDciHdgYPpd8pPRTfRgsduuFLytAGNSJGbh8pHM8HsMkvk61kacRkQZnAkC7Z
62fTeZ/eBwKlJSiAFWhWvDKwhI4HO67zd7fSk0V/Jy/pwNTs2uz4cAI9AgMBAAGj
EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAR9de5UkxKP
ae2+BBRbhRSQ6awjCk8R22HZv1aYdUaTcci9Ky4pQL+VgtzXNzTgDpNloLEHK7FR
+DHEHsO82uPwc7CC5lzHtCGrsYOb51gah3EnzLnG6pKvd7XwAYQStuxdCvlsSuFf
oACirqbNEhZT4Q6BaTzeH3X9pcptMb0CwAYcG1Rhebrl89TCocyQSUCKmJzuTEy5
NYM+cGD6p3KXkiKzWssYd/fq7V9/4ah9Oxex4x80fnHF5gUY3xRUywyb+ZcR32z3
UZddf1C6Kup943AjsU6NEYXWGrCNAThmuhVnBgTWOjVshbV7rOeQtc8Ou1C5MC4k
NWQTpFABwX8=
-----END CERTIFICATE-----

我使用 KeyStore Explorer 创建了一个信任库。实际的java代码如下所示:

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

public class App {

    public static void main(String[] args) {
        System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore.p12");
        System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

        String url = "jdbc:mysql://localhost:33060/mysql?verifyServerCertificate=true&useSSL=true&requireSSL=true";
        try (Connection connection = DriverManager.getConnection(url, "root", "secret")) {
            System.out.println("Database connected!");
        } catch (SQLException e) {
            throw new IllegalStateException("Cannot connect the database!", e);
        }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.