Running a .sql script using MySQL with JDBC

2019-01-02 19:53发布

I am starting to use MySQL with 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)" +
            ")");

I have 3-4 tables to create and this doesn't look good.

Is there a way to run a .sql script from MySQL JDBC?

12条回答
柔情千种
2楼-- · 2019-01-02 20:35

Write code to:

  1. Read in a file containing a number of SQL statements.
  2. Run each SQL statement.
查看更多
素衣白纱
3楼-- · 2019-01-02 20:37

Spring Framework's ResourceDatabasePopulator may help. As you said you're using MySQL and JDBC, let's assume you have a MySQL-backed DataSource instance ready. Further, let's assume your MySQL script files are classpath-locatable. Let's assume you are using WAR layout and the script files are located in a directory src/main/webapp/resources/mysql-scripts/... or src/test/resources/mysql-scripts/.... Then you can use ResourceDatabasePopulator to execute SQL scripts like this:

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();
    }
查看更多
旧人旧事旧时光
4楼-- · 2019-01-02 20:39

For Oracle PL/SQL, the Oracle JDBC-driver indeed supports executing entire SQL-scripts including stored procedures and anonymous blocks (PL/SQL specific notation), see

Can the JDBC Drivers access PL/SQL Stored Procedures?

The Oracle JDBC driver FAQ has more info:

Oracle JDBC drivers support execution of PL/SQL stored procedures and anonymous blocks. They support both SQL92 escape syntax and Oracle PL/SQL block syntax. The following PL/SQL calls would work with any Oracle JDBC driver:

// 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

It should be possible to read in a file and feed the content to the prepareCall()-method.

查看更多
伤终究还是伤i
5楼-- · 2019-01-02 20:40

There isn't really a way to do this.

You could either run the mysql command line client via Runtime.exec(String[]) and read this article when you decide for this option

Or try using the ScriptRunner (com.ibatis.common.jdbc.ScriptRunner) from ibatis. But it's a bit stupid to include a whole library just to run a script.

查看更多
琉璃瓶的回忆
6楼-- · 2019-01-02 20:42

Another interesting option would be to use Jisql to run the scripts. Since the source code is available, it should be possible to embed it into an application.


Edit: took a careful look at it; embedding it inside something else would require some modification to its source code.

查看更多
妖精总统
7楼-- · 2019-01-02 20:47

For simple sql script splitted by ';' you can use this simple function. It remove comments and run statements one by one

  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();
    }
  }
查看更多
登录 后发表回答