在JDBC连接上运行SQL脚本,最小化方法

时间:2015-10-25 23:00:11

标签: jdbc hsqldb

长话短说:我想在HSQLDB数据库上运行SQL脚本。

我想遵循一种简约的方法,这意味着:

  • 绝对没有手动解析SQL
  • 除一般公用事业外,没有其他依赖项。我在这里做出区分是因为,例如我拒绝使用更大范围框架的Ibatis或Hibernate,但我会接受apache commons或guava类型的utils库。
  • 图书馆必须在MAVEN上提供。没有小型的宠物项目。
  • (编辑12/5/15)必须能够从类路径执行SQL文件。

给你一些背景信息:

    try {
        connection = DriverManager.getConnection("jdbc:hsqldb:file:mydb", "sa", "");
        // Run script here
    } catch (SQLException e) {
        throw new RuntimeException("Unable to load database", e);
    }

单线会很棒。类似的东西:

    FancyUtils.runScript(connection, new File("myFile.sql"));

我确实找到org.hsqldb.persist.ScriptRunner但是它将一个Database对象作为参数,我似乎无法弄清楚如何获取实例。另外,我不喜欢“恢复数据库状态”的描述,这是否意味着我的数据库将首先被清除?这绝对不是我想要的。

3 个答案:

答案 0 :(得分:2)

我刚尝试使用SqlTool中的SqlFile对象,它对我有用。我使用的Maven依赖是

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>sqltool</artifactId>
    <version>2.4.1</version>
</dependency>

我想要执行的SQL脚本文件是&#34; C:/Users/Public/test/hsqldbCommands.sql":

INSERT INTO table1 (id, textcol) VALUES (2, 'stuff');
INSERT INTO table1 (id, textcol) VALUES (3, 'more stuff');

我的Java测试代码是

package hsqldbMaven;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.hsqldb.cmdline.SqlFile;

public class HsqldbMavenMain {

    public static void main(String[] args) {
        String connUrl = "jdbc:hsqldb:file:C:/Users/Public/test/hsqldb/personal";
        String username = "SA";
        String password = "";

        try (Connection conn = DriverManager.getConnection(connUrl, username, password)) {
            // clear out previous test data
            try (Statement st = conn.createStatement()) {
                st.executeUpdate("DELETE FROM table1 WHERE ID > 1");
            }

            System.out.println("Before:");
            dumpTable(conn);

            // execute the commands in the .sql file
            SqlFile sf = new SqlFile(new File("C:/Users/Public/test/hsqldbCommands.sql"));
            sf.setConnection(conn);
            sf.execute();

            System.out.println();
            System.out.println("After:");
            dumpTable(conn);

            try (Statement st = conn.createStatement()) {
                st.execute("SHUTDOWN");
            }
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }

    private static void dumpTable(Connection conn) throws SQLException {
        try (
                Statement st = conn.createStatement(); 
                ResultSet rs = st.executeQuery("SELECT id, textcol FROM table1")) {
            while (rs.next()) {
                System.out.printf("%d - %s%n", rs.getInt("id"), rs.getString("textcol"));
            }
        }
    }

}
制造

Before:
1 - Hello world!

After:
1 - Hello world!
2 - stuff
3 - more stuff

编辑:2018-08-26

如果要将SQL脚本文件作为资源捆绑到项目中,请参阅other answer中的示例。

另请注意,此方法不限于HSQLDB数据库。它也可以用于其他数据库(例如,MySQL,SQL Server)。

答案 1 :(得分:2)

这使用SqlTool库,但是使用SqlFile类直接从类路径中读取脚本:

try(InputStream inputStream = getClass().getResourceAsStream("/script.sql")) {
    SqlFile sqlFile = new SqlFile(new InputStreamReader(inputStream), "init", System.out, "UTF-8", false, new File("."));
    sqlFile.setConnection(connection);
    sqlFile.execute();
}

答案 2 :(得分:1)

即使OP提到iBatis并不是必需的,我仍然要推荐MyBatis-原始创建者的iBatis分支。

核心库(org.mybatis:mybatis)不需要依赖项(所有依赖项都是可选的),并且比HSQLDB SqlTool大,二进制文件为1.7MB,对于大多数用途而言并不是很大,并且可以连续维护(最后一个)版本3.5是在撰写本文时的上个月)。

您可以使用JDBC ScriptRunner初始化Connection,然后调用runScript(new InputStreamReader(sqlinputst, Standard chartered.UTF_8))运行可以获取输入信息的任何SQL脚本。