web-dev-qa-db-fra.com

Exécution d'un script .sql à l'aide de MySQL avec JDBC

Je commence à utiliser MySQL avec JDBC.

Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///x", "x", "x");
stmt = conn.createStatement();
stmt.execute( "CREATE TABLE amigos" +
            "("+
            "id          int AUTO_INCREMENT          not null,"+
            "nombre      char(20)                    not null,"+
            "primary key(id)" +
            ")");

J'ai 3-4 tables à créer et cela n'a pas l'air bien.

Existe-t-il un moyen d'exécuter un script .sql à partir de MySQL JDBC?

65
Macarse

D'accord. Vous pouvez utiliser cette classe ici (publiée sur Pastebin en raison de la longueur du fichier) dans votre projet. Mais n'oubliez pas de conserver les informations de licence Apache.

JDBC ScriptRunner

C'est l'arnaque de l'iBatis ScriptRunner avec les dépendances supprimées.

Vous pouvez l'utiliser comme ceci

Connection con = ....
ScriptRunner runner = new ScriptRunner(con, [booleanAutoCommit], [booleanStopOnerror]);
runner.runScript(new BufferedReader(new FileReader("test.sql")));

C'est ça!

70
jitter

J'ai fait beaucoup de recherches à ce sujet et trouvé un bon tilisation à partir du printemps . Je pense que l'utilisation de SimpleJdbcTestUtils.executeSqlScript(...) est en fait la meilleure solution, car elle est plus maintenue et testée.

Modifier: SimpleJdbcTestUtils est obsolète. Vous devez utiliser JdbcTestUtils. Mise à jour du lien.

24
Amir Raminfar

ResourceDatabasePopulator de Spring Framework peut vous aider. Comme vous l'avez dit, vous utilisez MySQL et JDBC, supposons que vous disposez d'une instance DataSource soutenue par MySQL. De plus, supposons que vos fichiers de script MySQL soient localisables par chemin de classe. Supposons que vous utilisez la disposition WAR et que les fichiers de script se trouvent dans un répertoire src/main/webapp/resources/mysql-scripts/... ou src/test/resources/mysql-scripts/.... Ensuite, vous pouvez utiliser ResourceDatabasePopulator pour exécuter des scripts SQL comme celui-ci:

import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import javax.sql.DataSource;

DataSource dataSource = getYourMySQLDriverBackedDataSource();

ResourceDatabasePopulator rdp = new ResourceDatabasePopulator();    
rdp.addScript(new ClassPathResource(
                        "mysql-scripts/firstScript.sql"));
rdp.addScript(new ClassPathResource(
                        "mysql-scripts/secondScript.sql"));

try {
        Connection connection = dataSource.getConnection();
        rdp.populate(connection); // this starts the script execution, in the order as added
    } catch (SQLException e) {
        e.printStackTrace();
    }
15
Abdull

Pour un simple script sql divisé par ';' vous pouvez utiliser cette fonction simple. Il supprime les commentaires et exécute les instructions une par une

  static void executeScript(Connection conn, InputStream in)
    throws SQLException
  {
    Scanner s = new Scanner(in);
    s.useDelimiter("/\\*[\\s\\S]*?\\*/|--[^\\r\\n]*|;");

    Statement st = null;

    try
    {
      st = conn.createStatement();

      while (s.hasNext())
      {
        String line = s.next().trim();

        if (!line.isEmpty())
          st.execute(line);
      }
    }
    finally
    {
      if (st != null)
        st.close();
    }
  }
6
lunicon

@Pantelis Sopasakis

Version légèrement modifiée sur GitHub: https://Gist.github.com/831762/

Il est plus facile de suivre les modifications là-bas.

4
joe776

Concernant le script runner SQL (que j'utilise également), j'ai remarqué le morceau de code suivant:

for (int i = 0; i < cols; i++) {
  String value = rs.getString(i);
  print(value + "\t");
}

Cependant, dans la documentation de l'API pour la méthode getString (int), il est mentionné que les index commencent par 1 , cela devrait donc devenir:

for (int i = 1; i <= cols; i++) {
  String value = rs.getString(i);
  print(value + "\t");
}

Deuxièmement, cette implémentation de ScriptRunner ne prend pas en charge les instructions [~ # ~] délimiteur [~ # ~] dans le script SQL qui sont importantes si vous besoin de compiler des DÉCLENCHEURS ou des PROCÉDURES. J'ai donc créé cette version modifiée de ScriptRunner: http://Pastebin.com/ZrUcDjSx que j'espère que vous trouverez utile.

2
Pantelis Sopasakis

Pouvez-vous utiliser ceci:

public static void executeSQL(File f, Connection c) throws Exception {
    BufferedReader br = new BufferedReader(new FileReader(f));
    String sql = "", line;
    while ((line = br.readLine()) != null) sql += (line+"\n");
    c.prepareCall(sql).execute(sql);
}

Cette fonction obtient le fichier SQL et la connexion DB. Il lit ensuite le fichier ligne par ligne à l'aide de BufferedReader de Java.io.
Et, enfin, exécute les instructions de lecture.

Version Java 8+:

public static void executeSQL(Path p, Connection c) throws Exception {
    List<String> lines = Files.readAllLines(p);
    String s = String.join("\n", lines.toArray(new String[0]));
    c.prepareCall(s).execute(s);
}
2
Muskovets

Une autre option intéressante serait d'utiliser Jisql pour exécuter les scripts. Le code source étant disponible, il devrait être possible de l'intégrer dans une application.


Edit: y a jeté un œil attentif; l'incorporer dans quelque chose d'autre nécessiterait une modification de son code source.

2
Haroldo_OK

Pour Oracle PL/SQL, le pilote Oracle JDBC prend en charge l'exécution de scripts SQL entiers, y compris les procédures stockées et les blocs anonymes (notation spécifique PL/SQL), voir

Les pilotes JDBC peuvent-ils accéder aux procédures stockées PL/SQL?

--- FAQ sur le pilote Oracle JDBC contient plus d'informations:

Les pilotes Oracle JDBC prennent en charge l'exécution des procédures stockées PL/SQL et des blocs anonymes. Ils prennent en charge la syntaxe d'échappement SQL92 et la syntaxe de bloc Oracle PL/SQL. Les appels PL/SQL suivants fonctionneraient avec n'importe quel pilote Oracle JDBC:

// SQL92 syntax
CallableStatement cs1 = conn.prepareCall
                       ( "{call proc (?,?)}" ) ; // stored proc
CallableStatement cs2 = conn.prepareCall
                       ( "{? = call func (?,?)}" ) ; // stored func
// Oracle PL/SQL block syntax
CallableStatement cs3 = conn.prepareCall
                       ( "begin proc (?,?); end;" ) ; // stored proc
CallableStatement cs4 = conn.prepareCall
                       ( "begin ? := func(?,?); end;" ) ; // stored func

Il devrait être possible de lire un fichier et d'alimenter le contenu de la méthode prepareCall ().

1
Gregor

Maven SQL Plugin Utilisez ce plugin pour exécuter des instructions SQL via un fichier ou une liste de fichiers via

  1. sqlCommand
  2. configurations de srcFiles 3.fileset
1
kapil das

Écrivez le code à:

  1. Lisez un fichier contenant un certain nombre d'instructions SQL.
  2. Exécutez chaque instruction SQL.
1
matt b

Il n'y a pas vraiment de moyen de le faire.

Vous pouvez soit exécuter le client de ligne de commande mysql via Runtime.exec (String []) et lire cet article lorsque vous décidez pour cette option

Ou essayez d'utiliser le ScriptRunner (com.ibatis.common.jdbc.ScriptRunner) de ibatis . Mais c'est un peu stupide d'inclure une bibliothèque entière juste pour exécuter un script.

0
jitter