我正在编写一个使用本地SQL数据库存储数据的程序。
我正在使用在这里找到的驱动程序:https : //bitbucket.org/xerial/sqlite-jdbc
我试图从数据库中读取并将tableName的内容放入这样的JTable中:
public Object[][] getTable(String tableName){ int columns = getColumnNumber(tableName); int rows = getRowNumber(tableName); String[] columnNames = getColumnNames(tableName); Object[][] table = new Object[rows][columns]; try{ Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db"); Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("select * from " + tableName); for(int r = 0; r < rows; r++){ rs.next(); for (int c = 0; c < columns; c++){ table[r][c] = rs.getString(columnNames[c]); } } return table; }catch(Exception e){ System.out.println("ERROR CREATING TABLE ARRAY"); e.printStackTrace(); return null; } }
然后,稍后我尝试返回并向表中添加一行:
public boolean addRow(String tableName, Object[] values){ if(!isDataAcceptable(tableName, values)) return false; try{ String stmt = "insert into " + tableName + " values ("; for(int c = 0; c < values.length; c++){ if(values[c] instanceof String) stmt += "'" + values[c] + "'"; else stmt += values[c]; if(c == (values.length - 1)) stmt += ");"; else stmt += ", "; } System.out.println(stmt); Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db"); Statement statement = connection.createStatement(); statement.executeUpdate(stmt); return true; }catch(Exception e){ System.out.println("ERROR INSERTING ROW"); e.printStackTrace(); return false; } }
然后,我想用新行更新之前创建的JTable。
但是,当我尝试添加行时会导致异常:
java.sql.SQLException: database is locked
指向这一行:
statement.executeUpdate(stmt);
…在addRow()方法中。
为什么数据库被锁定?如何解锁数据库才能写入数据库?
该数据库很可能已锁定,addRow因为上一次调用getTable并未关闭结果集。该代码还无法关闭数据库连接对象,这将导致资源泄漏。
addRow
getTable
基本的解决方法是调用close()在rs和connection对象,但你需要做的是正确的方法,使你的代码可靠。
close()
rs
connection
这是在Java 7中使用“尝试使用资源”语法的推荐方法:
try (Connection connection = DriverManager.getConnection("jdbc:sqlite:" + dbName + ".db"), Statement stmt = connection.createStatement(), ResultSet rs = stmt.executeQuery("select * from " + tableName)) { for (int r = 0; r < rows; r++) { rs.next(); for (int c = 0; c < columns; c++) { table[r][c] = rs.getString(columnNames[c]); } } return table; } catch (Exception e) { System.out.println("ERROR CREATING TABLE ARRAY"); e.printStackTrace(); return null; }
您也可以通过close在一个finally块中显式调用来执行此操作,但这更加冗长,并且如果您有需要关闭的相关资源,则代码可能很难正确使用…像这里一样。
close
finally