java.sql.SQLException: ResultSet 根据主定义的顺序更新时关闭 class

java.sql.SQLException: ResultSet closed when updating based on the order of definition in the main class

我有一个 class,它将连接到它自己的 SQLite 数据库,并具有与数据库交互的功能。在我的代码 customerDBmerchantDB 中有两个 class 实例。出于某种原因,如果我在 class 的定义之后尝试调用 addBalance();reduceBalance(); 函数,那么在 class 中首先定义的实例将抛出错误class.

的其他实例

我在这个实例中得到的错误是:

Exception in thread "main" java.sql.SQLException: ResultSet closed

当我最初尝试稍后在主程序中调用 addBalance(); 时,出现错误:

Exception in thread "main" java.sql.SQLException: database connection closed

我在我的 Java 程序中使用 JBDC 库,数据库中的 users table 两个数据库的布局完全相同。任何帮助将不胜感激。

Users.db

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UsersDB {
    private static Connection conn = null;
    
    private boolean loggedIn = false;
    private boolean merchant = false;
    private String username;
    private float balance;
    
    public UsersDB(String dbName, boolean merchant) {
        this.merchant = merchant;
        // try to connect to DB
        try {
            Class.forName("org.sqlite.JDBC");
            conn = DriverManager.getConnection("jdbc:sqlite:" + dbName);
        } catch (Exception e) {
            System.out.println("Error - " + e.getMessage());
        }
    }
    
    public void login(String username, String password) throws NoSuchAlgorithmException, SQLException {
        
        // Check the fields contain data and that the user is not already logged in
        if (!Util.isNullOrEmpty(username) && !Util.isNullOrEmpty(password) && loggedIn == false) {
            ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM users WHERE username = '" + username + "'");
            
            // Check if username exists
            if (rs.next()) {
                String passwordInDB = rs.getString("password");
                
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                byte[] passwordHash = digest.digest(password.getBytes(StandardCharsets.UTF_8));
                
                // Check if passwords match
                if (Util.bytesToHex(passwordHash).equals(passwordInDB)) {
                    loggedIn = true;
                    
                    this.username = username;
                    balance = rs.getFloat("balance");
                    System.out.println("Successful login, " + this.username);
                }
            } else {
                System.out.println("Incorrect Username or Password");
            }
            
        } else {
            System.out.println("Sorry, there was an error logging in!");
        }
    }
    
    public float getBalance() throws SQLException {
        if (loggedIn) {
            ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM users WHERE username = '" + username + "'");          
            return rs.getFloat("balance");          
        }
        else {
            System.out.println("Action may not be performed. User must be logged in.");
        }
        return 0;
    }
    
    public void reduceBalance(float price) throws Exception {
        // User must be logged in to update balance
        // Price must be valid and not exceed the user's balance
        if (loggedIn && price > 0 && getBalance() >= price) {
            float newBalance = balance - price;
            conn.createStatement().executeUpdate("UPDATE users SET balance = " + newBalance + " WHERE username = '" + username + "'");
            // Update the value of balance to the new once stored in the database
            balance = getBalance();
            if (balance != newBalance) {
                throw new Exception("Balance Update Failed");
            } else {
                System.out.println("Customer balance decreased by " + price);
                System.out.println("");
            }
        }
        else {
            System.out.println("Cannot reduce balance");
            System.out.println("");
        }
    }
    
    public void addBalance(float price) throws Exception {
        if (loggedIn && price > 0) {
            float newBalance = balance + price;
            conn.createStatement().executeUpdate("UPDATE users SET balance = " + newBalance + " WHERE username = '" + username + "'");
            // Update the value of balance to the new once stored in the database
            balance = getBalance();
            if (balance != newBalance) {
                throw new Exception("Balance Update Failed");
            }
        } else {
            System.out.println("Cannot add balance");
        }
    }
    
    public boolean isLoggedIn() {
        return loggedIn;
    }
    
    public boolean isMerchant() {
        return merchant;
    }
    
    public void closeConnection() throws SQLException {
        conn.close();
    }
}

Definition

UsersDB merchantDB = new UsersDB("Merchants.db", true);
        merchantDB.login("merchant", "merchantpass");
        // Works
        merchantDB.addBalance(20);
        
        UsersDB customerDB = new UsersDB("Customers.db", false);
        customerDB.login("test", "testpass");   
        
        // Does not work
        merchantDB.addBalance(20);

您已将连接定义为静态:

private static Connection conn = null;

这意味着 class UsersDB 的所有实例将使用相同的连接。

从定义中删除关键字 static