2016-09-12 1 views
0

Je suis en train d'exécuter des commandes SQL de Java à l'aide ProcessBuilder. Mon problème est que je ne peux pas utiliser le même cmd de différentes fonctions. Par exemple, je veux exécuter un fichier SQL lorsque j'appuie sur un bouton. Après cela, je veux maintenir la connexion à sql plus et valider ou annuler la transaction en appuyant sur un autre bouton. Comment garder le processus d'un bouton à l'autre?Essayer d'exécuter des commandes SQL de java

Mon premier code de bouton:

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."); 
    } 

}

Code bouton Second:

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

Indice: vous n'avez jamais ** jamais de blocs de saisie vides. Ensuite: lisez les conventions de nommage Java. vous n'utilisez pas "_" dans les noms de variables; les noms de variables vont camelCase. Et vraiment important: vous voulez que nous passions ** notre ** temps pour vous aider. Vous prenez donc le temps nécessaire pour formater/indenter ** tout ** correctement votre entrée. – GhostCat

+0

Et puis: éviter la duplication de code. Le code pour mettre à jour votre txtArea est presque identique. Ne fais pas ça. – GhostCat

+0

Veuillez fournir quelques explications supplémentaires sur votre code, ce que vous essayez de faire et le problème que vous rencontrez. Il est difficile de trouver une erreur dans des dizaines ou même des centaines de lignes de code. [Créez un * Exemple * minimal, complet et vérifiable] (http://stackoverflow.com/help/mcve) et lisez [Comment poser une bonne question?] (Http://stackoverflow.com/help/) comment demander). –

Répondre

0

Le commentaire de Serg vous donne la bonne direction: il faut une claire séparation des préoccupations ici. Vous n'écrivez pas une application qui, d'une manière ou d'une autre, fait tout en un seul endroit.

Vous commencez par définir une interface telle que

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

chacun d'entre eux avec des paramètres raisonnables et jeter des listes.

Ensuite, vous commencez à mettre en œuvre que les interfaces; similaire à ce que vous avez fait jusqu'à présent dans MyExec; mais: vous masquer toutes ces choses ProcessBuilder des utilisateurs de votre interface.

Signification: dans votre code actuel, vous avez des champs publics; et vous vous attendez à ce que votre code "bouton" utilise ces champs. Et c'est mauvais. Au lieu de cela, votre code de bouton devrait appeler des méthodes (non statiques!) Sur une instance de cette interface. Et la mise en œuvre de cette interface permet de s'assurer que les bonnes choses arrivent.

Vous absolument ne pas continuer votre approche actuelle (où une classe ouvre cours d'eau, et d'autres classes juste « append » à ces cours d'eau, ou lire les).

+0

ce que vous dites n'est pas pour une connexion JDBC? Oui tu as raison. J'essaie d'ouvrir cmd à partir d'une fonction et ajouter des commandes à partir d'autres fonctions – Aleksandr8894

+0

Je dis que ** peu importe ** ce que vous faites; vous devriez "abstraire" de cela. Un utilisateur de cette interface ne devrait pas avoir besoin de savoir. Tout ce qu'il sait, c'est qu'il y a plusieurs méthodes qui doivent être appelées dans un certain ordre; et qui fait des choses significatives. – GhostCat

+0

je sais abot champs publics, mais je les utilise pour gagner du temps, c'est un code de test, après o trouver une solution je vais le faire ... – Aleksandr8894