51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

使用 Java 通过 SSH 连接远程 MySQL 数据库

1、概览 {#1概览}

Secure Shell(SSH)允许我们安全地访问和管理远程系统,包括执行命令、传输文件和隧道服务。

我们可以通过 SSH 会话建立与远程 MySQL 数据库的连接。Java 有多个 SSH 客户端,其中最常见的是 Java Secure Channel(JSch)

本文将带你了解如何通过 SSH 会话连接到运行在远程服务器上的 MySQL 数据库。

2、了解 SSH 端口转发 {#2了解-ssh-端口转发}

端口转发允许通过在 SSH 连接上将流量从本地端口重定向到远程服务器上的端口,从而实现客户系统和远程服务器之间的数据传输。

当防火墙或其他限制阻止直接连接远程服务器的 IP 和端口时,这一点尤其有用。

在本例中,MySQL 服务器运行在远程服务器的 localhost 上,通常使用 3306 端口。虽然从技术上讲,可以直接连接到远程服务器的 IP 和 MySQL 端口,但出于安全考虑,这通常会受到限制(3306 端口未开放)。相反,我们可以通过 SSH 使用本地端口转发来建立与数据库的安全连接。

在本地端口转发中,我们在本地机器上分配一个可用端口,并将其与远程运行的 MySQL 服务器端口绑定,以允许我们的程序与远程服务器之间进行数据通信。

3、Maven 依赖 {#3maven-依赖}

首先,在 pom.xml 中添加 JSchMySQL 驱动依赖:

<dependency>
    <groupId>com.github.mwiede</groupId>
    <artifactId>jsch</artifactId>
    <version>0.2.20</version>
</dependency>

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>9.0.0</version>
</dependency>

JSch 提供了 Session 等类,这些类对于建立与远程服务器的 SSH 连接至关重要。此外,MySQL 驱动允许我们与运行中的 MySQL 服务器建立连接。

4、连接配置 {#4连接配置}

定义与远程服务器的连接配置:

private static final String HOST = "HOST";
private static final String USER = "USERNAME";
private static final String PRIVATE_KEY = "PATH_TO_PRIVATEKEY";
private static final int PORT = 22;

在上面的代码中,我们定义了创建 SSH 会话所需的凭证。接下来,定义与远程数据库的连接配置:

private static final String DATABASE_HOST = "localhost";
private static final int DATABASE_PORT = 3306;
private static final String DATABASE_USERNAME = "DATABASE_USERNAME";
private static final String DATABASE_PASSWORD = "DATABASE_PASSWORD";

MySQL 数据库运行在远程机器的 localhost 上,使用 3306 端口。我们定义了数据库用户名和密码,用于验证连接。

5、创建 SSH 会话 {#5创建-ssh-会话}

连接信息定义后,让我们创建一个 JSch 实例来启动与远程服务器的连接:

JSch jsch = new JSch();
jsch.addIdentity(PRIVATE_KEY);

如上,我们使用私钥来验证身份。当然,也可以使用基于密码的身份认证。

接着,创建一个新的 SSH 会话(Session):

Session session = jsch.getSession(USER, HOST, PORT);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();

代码如上,我们创建了一个新会话,为了便于测试,我们禁用了 Host Key 检查,但在生产环境中,出于安全考虑应避免这样做。

最后,调用 Session 对象上的 connect() 方法来打开一个新的 SSH 会话。

6、通过端口转发连接 MySQL {#6通过端口转发连接-mysql}

接下来,使用 SSH 端口转发来隧道传输 MySQL 端口:

int port = session.setPortForwardingL(0, DATABASE_HOST, DATABASE_PORT);

代码如上,我们调用了 Session 对象上的 setPortForwardingL() 方法来设置本地端口转发。通过传递 0 作为本地端口,程序会动态选择一个可用的本地端口,将流量转发到远程 MySQL 服务器的 3306 端口。

端口转发(隧道)允许发送到本地端口的流量通过 SSH 连接转发到远程计算机上的 MySQL 服务器。

现在,让我们使用转发端口来连接 MySQL 服务器:

String databaseUrl = "jdbc:mysql://" + DATABASE_HOST + ":" + port + "/baeldung";
Connection connection = DriverManager.getConnection(databaseUrl, DATABASE_USERNAME, DATABASE_PASSWORD);

如上,我们使用 JDBC Connection 类建立了与数据库的连接。在数据库 URL 中,我们使用转发的本地端口,而不是远程 MySQL 服务器的默认端口(3306)。

此外,还要验证连接是否有效,断言与数据库的连接(connection)不是 null

assertNotNull(connection);

7、简单的查询 {#7简单的查询}

现在,让我们在已建立的连接上执行一些数据库操作。首先,创建一个表:

String createTableSQL = "CREATE TABLE test_table (id INT, data VARCHAR(255))";
try (Statement statement = connection.createStatement()) {
    statement.execute(createTableSQL);
}

如上,在 baeldung 数据库中创建了一个 test_table 表。

接下来,在创建的表中插入一条记录:

String insertDataSQL = "INSERT INTO test_table (id, data) VALUES (1, 'test data')";
try (Statement statement = connection.createStatement()) {
    statement.execute(insertDataSQL);
}

最后,断言创建的表已存在于数据库中:

try (Statement statement = connection.createStatement()) {
    ResultSet resultSet = statement.executeQuery("SHOW TABLES LIKE 'test_table'");
    return resultSet.next();
} 

8、关闭连接 {#8关闭连接}

一样的,操作完毕后需要关闭 SSH 会话和数据库连接:

session.disconnect();
connection.close();

如上,在 SessionConnection 对象上分别调用了 disconnect()close() 方法,以释放资源,防止潜在的内存泄漏。

9、总结 {#9总结}

本文介绍了 SSH 和 SSH 端口转发,以及如何使用 Java 通过 SSH 连接远程 MySQL 数据库。


Ref:https://www.baeldung.com/java-ssh-remote-mysql-db-connection

赞(4)
未经允许不得转载:工具盒子 » 使用 Java 通过 SSH 连接远程 MySQL 数据库