HSQLDB .script 文件
Posted
技术标签:
【中文标题】HSQLDB .script 文件【英文标题】:HSQLDB .script file 【发布时间】:2012-02-08 10:26:46 【问题描述】:我以文件模式启动 HSQLDB。它运行得很好。当我的 Java 代码结束时,我通过发出 SHUTDOWN 优雅地关闭 HSQLDB。这将删除创建的临时文件,例如 .lck 和 .log 等。
但是,即使在 SHUTDOWN 之后,也始终存在两个文件 - .script 和 .properties。
如果我们想重新启动 HSQLDB 并连接到已经存在的数据库,我知道使用 .script。那挺好的。但是这个文件包含原始数据,因此可以很容易地修改。这可能是一个安全问题。
有人可以建议最好的可行方法来处理这个问题吗?我应该对 .script 文件进行编码吗?我仍然希望在稍后阶段连接到已经创建的数据库,因为这是我运行文件模式而不是内存模式的唯一原因。我不想使用服务器(内存中)模式。
我在 Windows7 上使用 JDK 1.7.0_02 和 HSQLDB 2.2.5。
谢谢。
【问题讨论】:
【参考方案1】:如果你害怕有人直接看到.script文件的内容你可以加密它:
http://hsqldb.org/doc/2.0/guide/management-chapt.html#mtc_encrypted_database
这将阻止用户查看文件中的真实数据。
但这并不妨碍用户更改文件。如果用户对文件有物理访问权限,则无法阻止。
【讨论】:
感谢您的链接。这就是我一直在寻找的东西。但是, 1. 加密一般只有在有权访问加密密钥的用户是受信任的情况下才有效。这意味着必须向用户披露密钥。 2. 单个key不能用于多个数据库。是否有可能以某种方式在创建数据库时对其进行加密,并在稍后阶段访问它时自动解密(通过一些用户不知道的内部代码)。如果用户创建多个数据库,公开密钥仍然是一个令人头疼的问题。 密钥可以隐藏在您的应用程序中,而不向用户公开。您可以为多个数据库使用相同的预生成密钥。【参考方案2】:在这里使用这个例子 -> 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();
当服务器运行时,HSQLDB 将创建一个扩展名为 .lck
的文件,该文件将一直存在,直到服务器关闭。
要生成 AES 密钥,您可以使用 https://asecuritysite.com/encryption/keygen 或使用 CALL CRYPT_KEY('cypher_text', null);
这应该可以解决问题。
【讨论】:
以上是关于HSQLDB .script 文件的主要内容,如果未能解决你的问题,请参考以下文章
HSQLDB:.script 文件在多个项目执行[多线程环境]并行期间自动被删除?
如何让 HSQLDB 在从 .script 文件初始化数据源期间发出错误消息?