连接到sqlite数据库,执行准备好的Statement并关闭与java的连接的正确方法是什么?

时间:2018-06-09 10:23:46

标签: java sqlite jdbc

这是我目前的代码。我有或有几个问题:

  • 数据库正忙 - 错误
  • SQL错误或缺少数据库
  • 结果集已关闭

如果我想防止这两种错误,我应该使用哪种代码结构? 我需要连接try块吗?我需要在哪里关闭连接?我需要在哪里关闭preparedStatement?

到目前为止,我无法通过自己连接不同页面的信息来找到解决方案。

    public boolean checkForUser(String username){
        try(Connection con = this.connect();
                PreparedStatement pstmt = createPreparedStatementRegistrate(conn, username);
                ResultSet rs= pstmt.executeQuery();)
                {
                if (rueck.next()){
                    pstmt.close();
                    rs.close();
                    con.close();
                    //do some stuff
                }
        }catch(SQLException e){
            e.printStackTrace();
        }
        return null;
    }
private PreparedStatement createPreparedStatementRegistrate(Connection conn, String username) throws SQLException {
    String sql = "SELECT * FROM users WHERE username = ?";
    PreparedStatement pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, username);
    return pstmt;
}
private Connection connect() {
        String url = "jdbc:sqlite:user.db";
        Connection con = null;
        try {
            con = DriverManager.getConnection(url);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }
java.sql.SQLException: ResultSet closed
    at org.sqlite.core.CoreResultSet.checkOpen(CoreResultSet.java:69)
    at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:38)
    at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:443)
    at zugriffsverwaltung.Zugriffsverwaltung.loeschen(Zugriffsverwaltung.java:215)
    at zugriffsverwaltung.Zugriffsverwaltung.<init>(Zugriffsverwaltung.java:37)
    at main.Server.<init>(Server.java:29)
    at main.Server.main(Server.java:46)
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (Connection is closed)
    at org.sqlite.core.DB.newSQLException(DB.java:909)
    at org.sqlite.core.CoreStatement.internalClose(CoreStatement.java:115)
    at org.sqlite.jdbc3.JDBC3Statement.close(JDBC3Statement.java:35)
    at org.sqlite.jdbc4.JDBC4Statement.close(JDBC4Statement.java:27)
    at zugriffsverwaltung.Zugriffsverwaltung.loeschen(Zugriffsverwaltung.java:238)
    at zugriffsverwaltung.Zugriffsverwaltung.<init>(Zugriffsverwaltung.java:37)
    at main.Server.<init>(Server.java:29)
    at main.Server.main(Server.java:46)

1 个答案:

答案 0 :(得分:0)

问题是在使用结果集执行操作之前关闭结果集,语句和连接。这是不允许的:当您使用getString检索值时,需要打开结果集(未在代码中显示,但存在于堆栈跟踪中)。

当您使用try-with-resource时会在退出时关闭资源,甚至不必显式关闭。它看起来像SQLite驱动程序不符合JDBC要求,关闭已经关闭的资源应该是一个无操作,因为它抛出一个异常,即在关闭语句时关闭连接(可能是通过try-with-resources )。

您需要将代码更改为

public boolean checkForUser(String username){
    try(Connection con = this.connect();
            PreparedStatement pstmt = createPreparedStatementRegistrate(conn, username);
            ResultSet rs= pstmt.executeQuery();)
            {
            if (rueck.next()){
                //do some stuff
            }
    }catch(SQLException e){
        e.printStackTrace();
    }
    return null;
}

即删除行

pstmt.close();
rs.close();
con.close();