我正在开发一个提供数据库访问的简单Java库。目前我正在努力访问SQLite。我有一个名为SQlite.java的类,它只实现实例方法。以下是几种方法的实现:
public ResultSet retrieve(String query) {
try {
if (this.connection != null) {
this.statement = this.connection.createStatement();
return this.statement.executeQuery(query);
}
} catch (Exception e) {
System.err.println("[ERROR] " + e.getMessage());
}
return null;
}
public ResultSet listTables() {
try {
return this.retrieve("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name");
} catch (Exception e) {
System.err.println("[ERROR] " + e.getMessage());
}
return null;
}
public boolean hasTable(String tableName) {
try {
ResultSet rs = this.listTables();
while (rs.next()) {
if (rs.getString(1).equals(tableName)) {
return true;
}
}
} catch (Exception e) {
System.err.println("[ERROR] " + e.getMessage());
}
return false;
}
public void update(String query) {
try {
if (this.connection != null) {
this.statement = this.connection.createStatement();
this.statement.executeUpdate(query);
}
} catch (Exception e) {
System.err.println("[ERROR] " + e.getMessage());
}
}
public void dropTable(String tableName) {
try {
if (this.hasTable(tableName)) {
this.update("DROP TABLE " + tableName); // TEST!
} else {
System.err.println("[ERROR] Table '" + tableName + "' not found!");
}
} catch (Exception e) {
System.err.println("[ERROR] " + e.getMessage());
}
}
当我测试dropTable()方法时,我得到一个异常,说“数据库表被锁定”。我猜这是因为可能在hasTable()方法中调用的非关闭SELECT语句。据我所知,即使运行检索查询,数据库表也会被锁定,以便在其他人尝试选择数据时无法更新表。但是如何解决这个问题,我无法确定。有什么想法吗?
答案 0 :(得分:1)
我不知道您的环境是什么,但您应该使用带有连接池的数据源并检索并关闭每个事务的连接。
完美的方法可能是使用容器( Spring或Java EE one)让他为你管理事务,这样你就不介意正确管理JDBC资源。您还可以指定是否允许更新当前事务并管理其他事务属性,例如隔离。
如果您绝对想直接使用jdbc,最佳做法仍然是在使用后关闭连接。如果您因为不明原因而希望保持读取连接的存在,我建议使用2个不同的用户,一个用户只能进行只读访问,另一个用于更新,每次通话后系统关闭连接。
在任何情况下,您必须在使用后正确释放连接和最终准备好的语句,否则您将尝试死锁和/或内存泄漏。
比照http://javarevisited.blogspot.fr/2012/08/top-10-jdbc-best-practices-for-java.html