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

问题描述 投票:0回答:3

简而言之:我想在HSQLDB数据库上运行SQL脚本。

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

  • 绝对没有手动解析SQL
  • 除了一般的Utilities之外没有其他依赖项。我在这里做出区分是因为,例如我拒绝接受更大范围框架的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对象作为参数,我似乎无法弄清楚如何获取实例。另外,我不喜欢“恢复数据库状态”的描述,这是否意味着我的数据库将首先被清除?这绝对不是我想要的。

jdbc hsqldb
3个回答
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
投票

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

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

我想要执行的SQL脚本文件是“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
投票

虽然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脚本。

© www.soinside.com 2019 - 2024. All rights reserved.