2013-03-23 53 views
3

我在写一个使用本地SQL数据库存储数据的程序。JDBC SQL数据库被锁定?

我使用的驱动程序在这里找到:https://bitbucket.org/xerial/sqlite-jdbc

我试图从数据库中读取并把表名的内容复制到一个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()方法。

为什么数据库被锁定,我该如何解锁才能写入数据库?

+0

您不关闭任何您创建的对象,既不是'ResultSet'也不是'Statement',也不''Connection'。我会怀疑那是你的问题。 – 2013-03-23 23:17:14

+0

我对SQL非常陌生,以为它们是本地资源,它们在方法结束时会关闭。我如何关闭它们? – user1113827 2013-03-23 23:18:55

+0

就像其他任何外部资源是Java一样,当你完成后你需要调用'close()'。通常使用'try finally'模式。 – 2013-03-23 23:20:38

回答

3

为什么数据库被锁定,我该如何解锁才能写入它?

该数据库是最有可能锁定在addRow因为getTable以前调用没有关闭的结果集。该代码也无法关闭会导致资源泄漏的数据库连接对象。

基本的解决办法是呼吁rsconnection对象close(),但你需要做的是正确的方法,使你的代码可靠。

这里推荐的方式做到这一点在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; 
} 

您也可以通过在finally块调用close明确地做到这一点,但它是更冗长,如果您有需要关闭的相关资源,代码可能很难正确对待......就像这里。