2009-12-28 148 views
30

如何通过java应用程序通过SSH连接到远程MySQL数据库。小代码示例对我很有帮助,我会很感激。使用java通过ssh连接到远程mysql数据库

+0

看看[这个答案](http://stackoverflow.com/questions/252258/java-sql-connection-extension -for-ssh)... – TofuBeer 2009-12-28 07:43:26

回答

33

我的理解是,你想访问运行在远程机器上的mysql服务器,并通过SSH隧道监听端口3306。

到本地计算机上的远程机器上使用命令行SSH客户端创建端口1234这样的隧道端口3306,你会从本地机器上键入以下命令:

ssh -L 1234:localhost:3306 mysql.server.remote 

要做到与Java相同,您可以使用SSH2的Java实现JSch。从它的网站:

JSch允许你连接到一个sshd服务器,使用端口转发,X11转发,文件传输等,并且可以将其功能集成到自己的Java程序。 JSch获得BSD格式许可证。

例如,看看PortForwardingL.java。连接会话后,使用类似jdbc:mysql://localhost:1234/[database]的连接URL来创建与MySQL的JDBC连接。

+0

是的,我根据你的指示完成了...谢谢 – 2013-01-03 08:13:05

+0

它不适合我..会话连接后,当我尝试连接到'localhost:[port]'时java,它会永远尝试像没有给出任何异常,但它不能连接到数据库。 任何帮助表示赞赏。 – harsh 2014-01-06 08:53:37

10

我的详细代码如下:

package mypackage; 
import java.sql.*; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.Session; 

public class UpdateMySqlDatabase { 
    static int lport; 
    static String rhost; 
    static int rport; 
    public static void go(){ 
     String user = "ripon"; 
     String password = "wasim"; 
     String host = "myhost.ripon.wasim"; 
     int port=22; 
     try 
      { 
      JSch jsch = new JSch(); 
      Session session = jsch.getSession(user, host, port); 
      lport = 4321; 
      rhost = "localhost"; 
      rport = 3306; 
      session.setPassword(password); 
      session.setConfig("StrictHostKeyChecking", "no"); 
      System.out.println("Establishing Connection..."); 
      session.connect(); 
      int assinged_port=session.setPortForwardingL(lport, rhost, rport); 
      System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport); 
      } 
     catch(Exception e){System.err.print(e);} 
    } 
    public static void main(String[] args) { 
     try{ 
      go(); 
     } catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
      System.out.println("An example for updating a Row from Mysql Database!"); 
      Connection con = null; 
      String driver = "com.mysql.jdbc.Driver"; 
      String url = "jdbc:mysql://" + rhost +":" + lport + "/"; 
      String db = "testDB"; 
      String dbUser = "wasim"; 
      String dbPasswd = "riponalwasim123"; 
      try{ 
      Class.forName(driver); 
      con = DriverManager.getConnection(url+db, dbUser, dbPasswd); 
      try{ 
      Statement st = con.createStatement(); 
      String sql = "UPDATE MyTableName " + 
        "SET email = '[email protected]' WHERE email='[email protected]'"; 

      int update = st.executeUpdate(sql); 
      if(update >= 1){ 
      System.out.println("Row is updated."); 
      } 
      else{ 
      System.out.println("Row is not updated."); 
      } 
      } 
      catch (SQLException s){ 
      System.out.println("SQL statement is not executed!"); 
      } 
      } 
      catch (Exception e){ 
      e.printStackTrace(); 
      } 
      } 
     } 
2
package framework.restapi.utils; 

import java.sql.*; 

import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.Session; 
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; 

import java.sql.Connection; 
import java.util.ArrayList; 
import java.util.List; 

public class SQLConnection { 
    private static Connection connection = null; 
    private static Session session = null; 

    private static void connectToServer(String dataBaseName) throws SQLException { 
     connectSSH(); 
     connectToDataBase(dataBaseName); 
    } 

    private static void connectSSH() throws SQLException { 
     String sshHost = ""; 
     String sshuser = ""; 
     String dbuserName = ""; 
     String dbpassword = ""; 
     String SshKeyFilepath = "/Users/XXXXXX/.ssh/id_rsa"; 

     int localPort = 8740; // any free port can be used 
     String remoteHost = "127.0.0.1"; 
     int remotePort = 3306; 
     String localSSHUrl = "localhost"; 
     /***************/ 
     String driverName = "com.mysql.jdbc.Driver"; 

     try { 
      java.util.Properties config = new java.util.Properties(); 
      JSch jsch = new JSch(); 
      session = jsch.getSession(sshuser, sshHost, 22); 
      jsch.addIdentity(SshKeyFilepath); 
      config.put("StrictHostKeyChecking", "no"); 
      config.put("ConnectionAttempts", "3"); 
      session.setConfig(config); 
      session.connect(); 

      System.out.println("SSH Connected"); 

      Class.forName(driverName).newInstance(); 

      int assinged_port = session.setPortForwardingL(localPort, remoteHost, remotePort); 

      System.out.println("localhost:" + assinged_port + " -> " + remoteHost + ":" + remotePort); 
      System.out.println("Port Forwarded"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    private static void connectToDataBase(String dataBaseName) throws SQLException { 
     String dbuserName = "sf2_showpad_biz"; 
     String dbpassword = "lOAWEnL3K"; 
     int localPort = 8740; // any free port can be used 
     String localSSHUrl = "localhost"; 
     try { 

      //mysql database connectivity 
      MysqlDataSource dataSource = new MysqlDataSource(); 
      dataSource.setServerName(localSSHUrl); 
      dataSource.setPortNumber(localPort); 
      dataSource.setUser(dbuserName); 
      dataSource.setAllowMultiQueries(true); 

      dataSource.setPassword(dbpassword); 
      dataSource.setDatabaseName(dataBaseName); 

      connection = dataSource.getConnection(); 

      System.out.print("Connection to server successful!:" + connection + "\n\n"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 


    private static void closeConnections() { 
     CloseDataBaseConnection(); 
     CloseSSHConnection(); 
    } 

    private static void CloseDataBaseConnection() { 
     try { 
      if (connection != null && !connection.isClosed()) { 
       System.out.println("Closing Database Connection"); 
       connection.close(); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 

    } 

    private static void CloseSSHConnection() { 
     if (session != null && session.isConnected()) { 
      System.out.println("Closing SSH Connection"); 
      session.disconnect(); 
     } 
    } 


    // works ONLY FOR single query (one SELECT or one DELETE etc) 
    private static ResultSet executeMyQuery(String query, String dataBaseName) { 
     ResultSet resultSet = null; 

     try { 
      connectToServer(dataBaseName); 
      Statement stmt = connection.createStatement(); 
      resultSet = stmt.executeQuery(query); 
      System.out.println("Database connection success"); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 

     return resultSet; 
    } 

    public static void DeleteOrganisationReferencesFromDB(String organisationsLike) { 
     try { 
      connectToServer("ServerName"); 
      Statement stmt = connection.createStatement(); 

      ResultSet resultSet = stmt.executeQuery("select * from DB1"); 

      String organisationsToDelete = ""; 
      List<String> organisationsIds = new ArrayList<String>(); 

      // create string with id`s values to delete organisations references 
      while (resultSet.next()) { 
       String actualValue = resultSet.getString("id"); 
       organisationsIds.add(actualValue); 
      } 

      for (int i = 0; i < organisationsIds.size(); i++) { 
       organisationsToDelete = " " + organisationsToDelete + organisationsIds.get(i); 
       if (i != organisationsIds.size() - 1) { 
        organisationsToDelete = organisationsToDelete + ", "; 
       } 
      } 

      stmt.executeUpdate(" DELETE FROM `DB1`.`table1` WHERE `DB1`.`table1`.`organisation_id` in (" + organisationsToDelete + ");"); 


     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      closeConnections(); 
     } 
    } 

    public static List<String> getOrganisationsDBNamesBySubdomain(String organisationsLike) { 
     List<String> organisationDbNames = new ArrayList<String>(); 
     ResultSet resultSet = executeMyQuery("select `DB`.organisation.dbname from `DB1`.organisation where subdomain like '" + organisationsLike + "%'", "DB1"); 
     try { 
      while (resultSet.next()) { 
       String actualValue = resultSet.getString("dbname"); 
       organisationDbNames.add(actualValue); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      closeConnections(); 
     } 
     return organisationDbNames; 
    } 

    public static List<String> getAllDBNames() { 
     // get all live db names incentral DB 
     List<String> organisationDbNames = new ArrayList<String>(); 
     ResultSet resultSet = executeMyQuery("show databases", "DB1"); 
     try { 
      while (resultSet.next()) { 
       String actualValue = resultSet.getString("Database"); 
       organisationDbNames.add(actualValue); 
      } 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      closeConnections(); 
     } 
     return organisationDbNames; 
    } 

     public static void deleteDataBasesByName(List<String> DataBasesNamesList) { 
     try { 
      connectSSH(); 
      int dataBasesAmount = DataBasesNamesList.size(); 
      for (int i = 0; i < dataBasesAmount; i++) { 
       connectToDataBase(DataBasesNamesList.get(i)); 

       Statement stmt = connection.createStatement(); 
       stmt.executeUpdate("DROP database `" + DataBasesNamesList.get(i) + "`"); 

      } 

     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      CloseDataBaseConnection(); 
      closeConnections(); 
     } 
    } 
} 
5
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.util.Properties; 

import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.JSchException; 
import com.jcraft.jsch.Session; 

public class CTestDriver { 
    private static void doSshTunnel(String strSshUser, String strSshPassword, String strSshHost, int nSshPort, 
      String strRemoteHost, int nLocalPort, int nRemotePort) throws JSchException { 
     final JSch jsch = new JSch(); 
     Session session = jsch.getSession(strSshUser, strSshHost, 22); 
     session.setPassword(strSshPassword); 

     final Properties config = new Properties(); 
     config.put("StrictHostKeyChecking", "no"); 
     session.setConfig(config); 

     session.connect(); 
     session.setPortForwardingL(nLocalPort, strRemoteHost, nRemotePort); 
    } 

    public static void main(String[] args) { 
     try { 
      String strSshUser = "ssh_user_name"; // SSH loging username 
      String strSshPassword = "abcd1234"; // SSH login password 
      String strSshHost = "your.ssh.hostname.com"; // hostname or ip or 
                  // SSH server 
      int nSshPort = 22; // remote SSH host port number 
      String strRemoteHost = "your.database.hostname.com"; // hostname or 
                    // ip of 
                    // your 
                    // database 
                    // server 
      int nLocalPort = 3366; // local port number use to bind SSH tunnel 
      int nRemotePort = 3306; // remote port number of your database 
      String strDbUser = "db_user_name"; // database loging username 
      String strDbPassword = "4321dcba"; // database login password 

      CTestDriver.doSshTunnel(strSshUser, strSshPassword, strSshHost, nSshPort, strRemoteHost, nLocalPort, 
        nRemotePort); 

      Class.forName("com.mysql.jdbc.Driver"); 
      Connection con = DriverManager.getConnection("jdbc:mysql://localhost:" + nLocalPort, strDbUser, 
        strDbPassword); 
      con.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      System.exit(0); 
     } 
    } 
} 
+0

提供解决方案的一些细节。 – 2016-03-26 21:18:30

+0

可以这样说,当你想用另一台主机连接到远程主机时,即连接到一台主机,并从那里连接到主机。这是为了安全。 – Ankur 2017-01-09 21:42:14

相关问题