'JDBC'에 해당되는 글 2건

  1. 2018.01.30 [Java] 동적 jdbc jar 로딩 소스
  2. 2016.10.21 [MYSQL] JDBC - ssh를 통한 mysql 접속
2018. 1. 30. 10:36

1. 배경 : 버전에 따라 정상 동작하지 않는 driver가 존재

          이에 버전에 따라 각자 jdbc driver를 로딩할 필요성이 존재함



2. 소스


Pick your JDBC driver at runtime

If you're going to do any sort of database activity in Java, you'll probably be using JDBC. Like ODBC before it, JDBC is a great way to insure that your program is free of any ties to the underlying database. Traditionally, the mechanism is that you put the JDBC driver somewhere in the classpath and then use class.forName() to find and load the driver.

One problem with this is that it presumes that your driver is in the classpath. This means either packaging the driver in your jar, or having to stick the driver somewhere (probably unpacking it too), or modifying your classpath.

"But why not use something like URLClassLoader and the overload of class.forName() that lets you specify the ClassLoader?" Because the DriverManager will refuse to use a driver not loaded by the system ClassLoader. Ouch!

The workaround for this is to create a shim class that implements java.sql.Driver. This shim class will do nothing but call the methods of an instance of a JDBC driver that we loaded dynamically. Something like this:

import java.sql.*;

class DriverShim implements Driver {
	private Driver driver;
	DriverShim(Driver d) {
		this.driver = d;
	}
	public boolean acceptsURL(String u) throws SQLException {
		return this.driver.acceptsURL(u);
	}
	public Connection connect(String u, Properties p) throws SQLException {
		return this.driver.connect(u, p);
	}
	public int getMajorVersion() {
		return this.driver.getMajorVersion();
	}
	public int getMinorVersion() {
		return this.driver.getMinorVersion();
	}
	public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException {
		return this.driver.getPropertyInfo(u, p);
	}
	public boolean jdbcCompliant() {
		return this.driver.jdbcCompliant();
	}
}

class test {
	public will_not_work() {
		URL u = new URL("jar:file:/path/to/pgjdbc2.jar!/");
		String classname = "org.postgresql.Driver";
		URLClassLoader ucl = new URLClassLoader(new URL[] { u });
		Class.forName(classname, true, ucl);
		DriverManager.getConnection("jdbc:postgresql://host/db", "user", "pw");
		// That will throw SQLException: No suitable driver
	}
	public will_work() {
		URL u = new URL("jar:file:/path/to/pgjdbc2.jar!/");
		String classname = "org.postgresql.Driver";
		URLClassLoader ucl = new URLClassLoader(new URL[] { u });
		Driver d = (Driver)Class.forName(classname, true, ucl).newInstance();
		DriverManager.registerDriver(new DriverShim(d));
		DriverManager.getConnection("jdbc:postgresql://host/db", "user", "pw");
		// Success!
	}

will_work() works because DriverShim was loaded by the system class loader, and the DriverManager doesn't care that it invokes a class that wasn't. We must perform the registration on the instance ourselves, because although Class.forName() will cause a registration to take place, that particular registration will fail for the same reason that will_not_work() fails.




# 참고

Posted by citrine
2016. 10. 21. 17:12

1. 원리 : ssh로 우선 접속 후 port 포워딩을 통해서 mysql에 붙는다.




2. 코드 샘플


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 = 'ripon.wasim@smile.com' WHERE email='peace@happy.com'";

          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();
          }
          }
        }


3. 참고

http://stackoverflow.com/questions/1968293/connect-to-remote-mysql-database-through-ssh-using-java

'[IT] DB' 카테고리의 다른 글

[DB2] 버전 찾기  (0) 2017.01.31
[ElasticSearch] Bitwise 연산하는 법  (0) 2016.11.04
[MSSQL] 페이지 처리 방법  (0) 2016.07.28
[POSTGRESQL] 에러시 세션 종료  (0) 2016.07.18
[Oracle] SID와 Service Name의 차이점  (0) 2016.07.06
Posted by citrine