HSQLDB .script文件

时间:2012-02-08 10:26:47

标签: java hsqldb

我以文件模式启动HSQLDB。它运行得很好。当我的Java代码结束时,我通过发出SHUTDOWN来优雅地关闭HSQLDB。这将删除创建的临时文件,如.lck和.log等。

然而,即使在SHUTDOWN之后总是存在两个文件 - .script和.properties。

我知道如果我们想重启HSQLDB并连接到已经存在的数据库,就会使用.script。非常好。但是这个文件包含原始数据,因此可以很容易地修改。这可能是一个安全问题。

有人可以建议最好的方法来解决这个问题吗?我应该编码.script文件吗?我仍然希望在稍后阶段连接到已经创建的数据库,因为这是我运行文件模式而不是内存模式的唯一原因。我不想使用服务器(内存)模式。

我在Windows7上使用JDK 1.7.0_02和HSQLDB 2.2.5。

感谢。

2 个答案:

答案 0 :(得分:3)

如果您害怕有人直接看到.script文件的内容,您可以加密它:

http://hsqldb.org/doc/2.0/guide/management-chapt.html#mtc_encrypted_database

这将阻止用户查看文件中的真实数据。

但这并不妨碍用户更改文件。如果用户具有对文件的物理访问权限,则无法阻止该操作。

答案 1 :(得分:1)

此处使用此示例 - > http://www.hsqldb.org/doc/1.8/guide/apb.html

我对代码做了一些小改动,它将使用AES密钥加密*.script文件。

<强>代码

package com.gollahalli.main;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import org.hsqldb.Server;

public class Testdb {

    Connection conn;                                                //our connnection to the db - presist for life of program

    // we dont want this garbage collected until we are done
    public Testdb(String db_file_name_prefix) throws Exception {

        Class.forName("org.hsqldb.jdbcDriver");

        conn = DriverManager.getConnection("jdbc:hsqldb:"
                + db_file_name_prefix, // filenames
                "sa", // username
                "");                      // password
    }

    public void shutdown() throws SQLException {

        Statement st = conn.createStatement();

        st.execute("SHUTDOWN");
        conn.close();    // if there are no other open connection
    }

//use for SQL command SELECT
    public synchronized void query(String expression) throws SQLException {

        Statement st = null;
        ResultSet rs = null;

        st = conn.createStatement();         // statement objects can be reused with

        rs = st.executeQuery(expression);    // run the query

        dump(rs);
        st.close();    // NOTE!! if you close a statement the associated ResultSet is

    }

//use for SQL commands CREATE, DROP, INSERT and UPDATE
    public synchronized void update(String expression) throws SQLException {

        Statement st = null;

        st = conn.createStatement();    // statements

        int i = st.executeUpdate(expression);    // run the query

        if (i == -1) {
            System.out.println("db error : " + expression);
        }

        st.close();
    }    // void update()

    public static void dump(ResultSet rs) throws SQLException {

        ResultSetMetaData meta = rs.getMetaData();
        int colmax = meta.getColumnCount();
        int i;
        Object o = null;

        for (; rs.next();) {
            for (i = 0; i < colmax; ++i) {
                o = rs.getObject(i + 1);    // Is SQL the first column is indexed

                // with 1 not 0
                System.out.print(o.toString() + " ");
            }

            System.out.println(" ");
        }
    }                                       //void dump( ResultSet rs )

    public static void main(String[] args) {

        Server server = new Server();
        server.setDatabasePath(0, "file:./RemindMe;crypt_key=604a6105889da65326bf35790a923932;crypt_type=AES");
        server.setDatabaseName(0, "RemindMe");
        server.start();

        Testdb db = null;

        try {
            db = new Testdb("RemindMe");
        } catch (Exception ex1) {

            return;                   // bye bye
        }

        try {

            db.update(
                    "CREATE TABLE sample_table ( id INTEGER IDENTITY, str_col VARCHAR(256), num_col INTEGER)");
        } catch (SQLException ex2) {

        }

        try {

            db.update(
                    "INSERT INTO sample_table(str_col,num_col) VALUES('Ford', 100)");
            db.update(
                    "INSERT INTO sample_table(str_col,num_col) VALUES('Toyota', 200)");
            db.update(
                    "INSERT INTO sample_table(str_col,num_col) VALUES('Honda', 300)");
            db.update(
                    "INSERT INTO sample_table(str_col,num_col) VALUES('GM', 400)");

            // do a query
            db.query("SELECT * FROM sample_table WHERE num_col < 250");

            // at end of program
            db.shutdown();
        } catch (SQLException ex3) {
        }

        server.shutdown();
    }    // main()
}    // class Testdb

查看main方法,其中包含以下行

Server server = new Server();
server.setDatabasePath(0, "file:./RemindMe;crypt_key=604a6105889da65326bf35790a923932;crypt_type=AES");
server.setDatabaseName(0, "RemindMe");
server.start();
.....
server.shutdown();

当服务器运行时,HS​​QLDB将创建一个扩展名为.lck的文件,该文件将一直存在,直到服务器关闭。

要生成AES密钥,您可以使用https://asecuritysite.com/encryption/keygen或使用CALL CRYPT_KEY('cypher_text', null);

这应该可以解决问题。