#java #database #sqlite #connection
Вопрос:
У меня есть класс, который будет подключаться к своей собственной базе данных SQLite и имеет функции для взаимодействия с базой данных. В моем коде есть два экземпляра этого класса customerDB
и merchantDB
. По какой-то причине экземпляр, определенный первым в основном классе, выдаст ошибку, если я попытаюсь вызвать функцию addBalance();
или reduceBalance();
после определения другого экземпляра класса.
Ошибка, которую я получаю в этом случае, заключается в следующем:
Исключение в потоке «основной» Исключение java.sql.SQLException: набор результатов закрыт
И когда я первоначально попытался позвонить addBalance();
позже в своей основной программе, я получил ошибку:
Исключение в потоке «основной» Исключение java.sql.SQLException: соединение с базой данных закрыто
Я использую библиотеку JBDC в своей Java-программе, и users
таблица внутри базы данных имеет точно такой же макет для обеих баз данных. Любая помощь будет признательна.
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) amp;amp; !Util.isNullOrEmpty(password) amp;amp; 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 amp;amp; price > 0 amp;amp; 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 amp;amp; 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);
Комментарии:
1. Опубликуйте полученное сообщение об ошибке.
2. @forpas Я обновил вопрос, включив в него сообщения об ошибках.
Ответ №1:
Вы определили соединение как статическое:
private static Connection conn = null;
Это означает, что все экземпляры класса UsersDB
будут использовать одно и то же соединение.
Удалите ключевое static
слово из его определения.
Комментарии:
1. Я не могу поверить, что не видел этого — это объясняет, почему сообщение об ошибке изменилось на «соединение закрыто» после закрытия соединения с customerDB. Спасибо.