我以文件模式启动HSQLDB。它运行得很好。当我的Java代码结束时,我通过发出SHUTDOWN来优雅地关闭HSQLDB。这将删除创建的临时文件,如.lck和.log等。
然而,即使在SHUTDOWN之后总是存在两个文件 - .script和.properties。
我知道如果我们想重启HSQLDB并连接到已经存在的数据库,就会使用.script。非常好。但是这个文件包含原始数据,因此可以很容易地修改。这可能是一个安全问题。
有人可以建议最好的方法来解决这个问题吗?我应该编码.script文件吗?我仍然希望在稍后阶段连接到已经创建的数据库,因为这是我运行文件模式而不是内存模式的唯一原因。我不想使用服务器(内存)模式。
我在Windows7上使用JDK 1.7.0_02和HSQLDB 2.2.5。
感谢。
答案 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();
当服务器运行时,HSQLDB将创建一个扩展名为.lck
的文件,该文件将一直存在,直到服务器关闭。
要生成AES密钥,您可以使用https://asecuritysite.com/encryption/keygen或使用CALL CRYPT_KEY('cypher_text', null);
这应该可以解决问题。