繁体   English   中英

使用 MySQL 和 JDBC 运行 a.sql 脚本

[英]Running a .sql script using MySQL with JDBC

我开始使用 MySQL 和 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)" +
            ")");

我要创建 3-4 个表,这看起来不太好。

有没有办法从 MySQL JDBC 运行 a.sql 脚本?

好。 您可以在此项目中使用此类(由于文件长度而在pastebin上发布)。 但请记住保留apache许可证信息。

JDBC ScriptRunner

这是删除了依赖项的iBatis ScriptRunner的ripoff。

你可以像这样使用它

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

而已!

我对此做了很多研究,并从春天找到了一个好的工具。 我认为使用SimpleJdbcTestUtils.executeSqlScript(...)实际上是最好的解决方案,因为它更加维护和测试。

编辑:不推荐使用SimpleJdbcTestUtils 您应该使用JdbcTestUtils 更新了链接。

Spring Framework的ResourceDatabasePopulator可能有所帮助。 正如您所说的那样,您正在使用MySQL和JDBC,我们假设您已准备好支持MySQL的DataSource实例。 此外,假设您的MySQL脚本文件是类路径可定位的。 假设您使用的是WAR布局,脚本文件位于目录src/main/webapp/resources/mysql-scripts/...src/test/resources/mysql-scripts/... 然后,您可以使用ResourceDatabasePopulator执行如下所示的SQL脚本:

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

对于由';'拆分的简单sql脚本 你可以使用这个简单的功能。 它逐个删除注释和运行语句

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

@Pantelis Sopasakis

在GitHub上稍微修改过的版本: https//gist.github.com/831762/

它更容易跟踪修改。

另一个有趣的选择是使用Jisql来运行脚本。 由于源代码可用,因此应该可以将其嵌入到应用程序中。


编辑:仔细看看; 将其嵌入其他内容需要对其源代码进行一些修改。

你能用这个:

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

此函数获取SQL文件和数据库连接。 然后它使用java.io中的BufferedReader逐行读取文件。
最后,执行read语句。

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

关于SQL脚本运行器(我也在使用),我注意到以下代码:

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

但是,在方法getString(int)的API文档中,提到索引以1开头 ,因此应该变为:

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

其次,ScriptRunner的这种实现不支持SQL脚本中的DELIMITER语句,如果您需要编译TRIGGERS或PROCEDURES,这些语句很重要。 所以我创建了ScriptRunner的这个修改版本: http ://pastebin.com/ZrUcDjSx,我希望你会发现它很有用。

编写代码:

  1. 读入包含许多SQL语句的文件。
  2. 运行每个SQL语句。

Maven SQL插件使用此插件通过执行SQL语句文件或文件列表

  1. 的SqlCommand
  2. srcFiles 3.fileset配置

对于Oracle PL / SQL,Oracle JDBC驱动程序确实支持执行整个SQL脚本,包括存储过程和匿名块(PL / SQL特定表示法),请参阅

JDBC驱动程序可以访问PL / SQL存储过程吗?

Oracle JDBC驱动程序常见问题解答有更多信息:

Oracle JDBC驱动程序支持PL / SQL存储过程和匿名块的执行。 它们支持SQL92转义语法和Oracle PL / SQL块语法。 以下PL / SQL调用适用于任何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

应该可以读入文件并将内容提供给prepareCall()方法。

没有办法做到这一点。

您可以通过Runtime.exec(String [])运行mysql命令行客户端,并在决定使用此选项时阅读本文

或者尝试使用ibatis的ScriptRunner(com.ibatis.common.jdbc.ScriptRunner)。 但是,为了运行脚本而包含整个库有点愚蠢。

这是一个对我有用的快速而肮脏的解决方案。

public void executeScript(File scriptFile) {
  Connection connection = null;
  try {
    connection = DriverManager.getConnection(url, user, password);
    if(scriptFile.exists()) {
      var buffer = new StringBuilder();
      var scanner = new Scanner(scriptFile);
      while(scanner.hasNextLine()) {
        var line = scanner.nextLine();
        buffer.append(line);
        // If we encounter a semicolon, then that's a complete statement, so run it.
        if(line.endsWith(";")) {
          String command = buffer.toString();
          connection.createStatement().execute(command);
          buffer = new StringBuilder();
        } else { // Otherwise, just append a newline and keep scanning the file.
          buffer.append("\n");
        }
     }
    }
    else System.err.println("File not found.");
  } catch (SQLException e) {
    e.printStackTrace();
} finally {
  if(connection != null) connection.close();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM