2016-09-12 2 views
0

ProcessBuilder를 사용하여 java에서 sql 명령을 실행하려고합니다. 내 문제는 내가 다른 기능에서 동일한 cmd를 사용할 수 없습니다. 예를 들어, 버튼을 누를 때 SQL 파일을 실행하려고합니다. 그 후, 나는 SQL Plus에 대한 연결을 유지하고 다른 버튼을 눌러 트랜잭션을 커밋하거나 롤백하려고합니다. 프로세스를 버튼에서 다른 버튼으로 유지하는 방법은 무엇입니까?java에서 sql 명령을 실행하려고 시도했습니다.

내 첫 번째 단추 코드 :

public class MyExec { 

    public static ProcessBuilder builder; 
    public static Process p; 
    public static BufferedReader bri; 
    public static BufferedReader bre; 
    public static BufferedWriter p_stdin; 

    public static void executeScript(String scriptName, String alias, String path, TextArea txtArea) throws IOException { 

    //obtaining sql script from a share folder 
     NtlmPasswordAuthentication userCred = new NtlmPasswordAuthentication("domain", 
        "user", "pass"); 
     SmbFile smbFile=new SmbFile("path" + scriptName, userCred); 
     File file = new File("D://" + scriptName); 
     try (InputStream in = smbFile.getInputStream()) { 
     Files.copy(smbFile.getInputStream(), file.toPath()); 
     } 

     //init shell 
     builder = new ProcessBuilder("cmd"); 
     builder.redirectErrorStream(true); 
     try { 
     p = builder.start(); 
     } catch (IOException e) { 
     System.out.println(e); 
     } 
     //get stdin of shell 
     p_stdin =new BufferedWriter(new OutputStreamWriter(p.getOutputStream())); 

     //executing commands in cmd 
     try { 
     p_stdin.write("sqlplus sys/[email protected]" + alias +" as sysdba"); 
     p_stdin.newLine(); 
     p_stdin.flush(); 
     p_stdin.write("@"+file.toPath()); 
     p_stdin.newLine(); 
     p_stdin.flush(); 
     } catch (IOException e) { 
     System.out.println(e); 
     } 

     // write stdout of shell (=output of all commands) 
     String line; 
     bri = new BufferedReader(new InputStreamReader(p.getInputStream())); 
        bre = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     while ((line = bri.readLine()) != null) { 
     txtArea.appendText(line + "\n"); 
     System.out.println(line + "\n"); 
     }     
     while ((line = bre.readLine()) != null) { 
     txtArea.appendText(line + "\n"); 
     System.out.println(line + "\n"); 
     } 

     System.out.println("Done."); 
    } 

}

두 번째 버튼 코드 :

는 SERG에서 코멘트는 당신에게 올바른 방향을주고있다
Thread t1 = new Thread(new Runnable() { 
    public void run() { 
    //commit the sql script which was run with the first button 
    try { 
     MyExec.p_stdin.write("commit"); 
     MyExec.p_stdin.newLine(); 
     MyExec.p_stdin.flush(); 
     MyExec.p_stdin.write("exit"); 
     MyExec.p_stdin.newLine(); 
     MyExec.p_stdin.flush(); 

     //output the result of commiting sql script 
     String line; 
     BufferedReader bri = new BufferedReader(new InputStreamReader(MyExec.p.getInputStream())); 
     BufferedReader bre = new BufferedReader (new InputStreamReader(MyExec.p.getErrorStream())); 
     while ((line = MyExec.bri.readLine()) != null) { 
      txtArea.appendText(line + "\n"); 
      System.out.println(line + "\n"); 
     } 
     MyExec.bri.close(); 
     while ((line = MyExec.bre.readLine()) != null) { 
      txtArea.appendText(line + "\n"); 
      System.out.println(line + "\n"); 
     } 
     MyExec.bri.close(); 
     System.out.println("Done."); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } 

    } 
    }); 
     //event on Commit button, running the thread above 
    public void commit(ActionEvent e) { 
     t1.start(); 
    } 
+0

힌트 : 절대로 ** 비어있는 catch 블록이 없습니다. 그런 다음 : Java 명명 규칙에 대해 읽어보십시오. 변수 이름에 "_"을 사용하지 마십시오. 변수 이름은 camelCase가됩니다. 그리고 정말로 중요합니다. ** 우리가 ** 당신을 돕기 위해 ** 시간을 보내길 원합니다. 따라서 입력 한 내용을 모두 포맷하거나 들여 쓰기하는 데 걸리는 시간이 필요합니다. – GhostCat

+0

다음 : 코드 중복을 피하십시오. txtArea를 업데이트하는 코드는 거의 동일합니다. 그러지 마. – GhostCat

+0

코드에 대한 설명, 현재 수행중인 작업 및 발생한 문제점에 대해 설명해주십시오. 수십 또는 수백 줄의 코드에서 오류를 찾기가 어렵습니다. [* 최소, 완료 및 검증 가능한 예제 만들기] (http://stackoverflow.com/help/mcve)를 읽고 [어떻게 좋은 질문을합니까?] (http://stackoverflow.com/help/)를 읽어보십시오. how-to-ask). –

답변

0

가 : 당신이 명확 분리 필요 여기에 우려의. 어떻게 든 모든 것을 한 곳에서하는 응용 프로그램 하나를 작성하지 마십시오.

당신은 다음과 같은 적절한 매개 변수를

interface SqlProvider { 
    public void connectConnection() ... 
    public void beginTransaction() ... 
    public void commit() .. 
    public void rollback() 
    public void endTransaction() 
    public voide closeConnection() 

그들 각각 던져 목록 인터페이스를 정의하여 시작합니다.

그런 다음 해당 인터페이스를 구현하기 시작합니다. 지금까지 MyExec에서했던 것과 비슷합니다. 하지만 : 을 숨기면 인터페이스 사용자의 모든 ProcessBuilder 항목을 숨길 수 있습니다.

의미 : 현재 코드에는 공개 입력란이 있습니다. "버튼"코드가 해당 필드를 사용할 것으로 기대합니다. 그리고 입니다. 대신 버튼 코드는 해당 인터페이스의 인스턴스에서 (정적이지 않은!) 메서드를 호출해야합니다. 그리고 그 인터페이스의 구현은 올바른 일이 일어나는지 확인합니다.

현재 접근을 계속하지 마십시오 (한 클래스가 스트림을 열고 다른 클래스가 해당 스트림에 "추가"되거나 읽히는 경우).

+0

당신은 JDBC 연결이 아니라고 말합니까? 네, 맞습니다. 함수에서 cmd를 열고 다른 함수에서 명령을 추가하려고합니다. – Aleksandr8894

+0

** 아무리 ** 당신이하는 일을 말하고 있습니다. 당신은 ** abstract **해야합니다. 해당 인터페이스의 사용자는 알 필요가 없습니다. 그가 알고있는 모든 것은 특정 순서로 호출되어야하는 몇 가지 방법이 있다는 것입니다. 그것은 의미있는 일을합니다. – GhostCat

+0

나는 abot public fields를 알고 있지만, 시간을 얻기 위해 그것들을 사용한다. 테스트 코드이다. 해결책을 찾은 후에 나는 그것을 만들 것이다 ... – Aleksandr8894

관련 문제