Hello Stackoverflow用户,
我目前遇到SQL连接问题。首先,这是连接器的处理方式
package com.rs.utils.sql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.rs.utils.Logger;
public class DatabaseManager {
private String host;
private String database;
private String username;
private String password;
private Connection connection;
private PreparedStatement statement;
private boolean connected;
public DatabaseManager() {
this.host = "";// Settings.DB_HOST;
this.database = "";// Settings.DB_NAME;
this.username = "";// Settings.DB_USER;
this.password = "";// Settings.DB_PASS;
this.connected = false;
}
public void connect() {
try {
connection = DriverManager.getConnection("jdbc:mysql://" + host
+ "/" + database
+ "?jdbcCompliantTruncation=false&autoReconnect=true",
username, password);
Logger.info("Successfully connected with " + host + "/" + database);
connected = true;
} catch (Exception e) {
Logger.info("Unable to connect with " + host + "/" + database + ".");
connected = false;
}
}
public ResultSet executeQuery(String query) {
try {
if (!connected())
return null;
statement = connection.prepareStatement(query);
ResultSet results = statement.executeQuery();
return results;
} catch (Exception e) {
Logger.handle(e);
}
return null;
}
public int executeUpdate(String query) {
try {
if (!connected())
return 0;
statement = connection.prepareStatement(query);
return statement.executeUpdate();
} catch (Exception e) {
Logger.handle(e);
}
return 0;
}
public boolean connected() {
return connected;
}
public PreparedStatement statement() {
return statement;
}
}
使用DatabaseManager实例将大量查询发送到数据库,例如:
databaseManager.executeUpdate(query);
databaseManager定义为:
private static DatabaseManager databaseManager = new DatabaseManager();
我得到以下Throwable:
java.sql.SQLException: Operation not allowed after ResultSet closed
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:803)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1126)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5732)
at com.rs.utils.sql.PlayerSaving.load(PlayerSaving.java:362)
at com.rs.utils.sql.PlayerLoader.load(PlayerLoader.java:90)
PlayerLoader中的加载方法:
public static boolean load(Player player, boolean lobby) {
ResultSet result = null;
try {
final long current = System.currentTimeMillis();
result = World.database().executeQuery("SELECT " + (lobby ? "displayName, rights" : "*") + " FROM " + PLAYER_TABLE + " WHERE username='" + player.getPlayerDefinition().username() + "' LIMIT 1");
if (!result.next()) {
return false;
}
if (lobby) {
player.getPlayerDefinition().setRights(result.getInt("rights")).setDisplayName(result.getString("displayName"));
} else {
**player.playerSaving().load(result);**
}
Logger.log("Loader", "Player loaded in " + (System.currentTimeMillis() - current) + "ms.");
return true;
} catch (Exception e) {
Logger.log("Loader", "Unable to load player profile.");
Logger.handle(e);
System.err.println("Error Loading the account.");
} finally {
try {
if (result != null) {
result.close();
}
result = null;
World.database().statement().close();
} catch (SQLException e) {
Logger.handle(e);
}
}
return false;
}
PlayerSaving加载方法只是将另一个类实例分配给数据库中的值与result.getInt(“rowName”)等,在ResultSet上收到,它超过250行
ResultSet在大多数情况下都很好,这是一个非常罕见的事件,比如100次登录尝试中的1次。但不知何故,ResultSet在变量赋值的中间被关闭,比如,它分配200个变量中的100个,然后ResultSet突然关闭并抛出异常。
有什么想法吗?
答案 0 :(得分:0)
关闭语句也将关闭基础ResultSet。你可能已经嵌套了对DatabaseManager的调用,这个调用只有一个共享的PreparedStatement,在我看来,这是一个坏主意。
(我没有足够的代表来添加评论,所以我不得不将其作为答案发布)
下面是为每个查询操作使用专用PreparedStatement和ResultSet的示例实现:
public List<MyDataClass> listMyData(Connection con, String partNumber) {
ArrayList<MyDataClass> list = new ArrayList<MyDataClass>();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = con.prepareStatement("SELECT PART_NO, DESC, PRICE FROM MYTABLE WHERE PART_NO = ?");
ps.setString(1, partNumber);
rs = ps.executeQuery();
while(rs.next()) {
MyDataClass myData = new MyDataClass();
myData.setPartNumber(rs.getString("PART_NO"));
myData.setDescription(rs.getString("DESC"));
myData.setPrice(rs.getBigDecimal("PRICE"));
list.add(myData);
}
con.commit();
}
catch(Throwable thrown) {
try{ con.rollback(); }catch(Throwable t){}
//Handle the exception here to log etc.
}
finally {
//Always close result set before statement
if(rs != null) { try{ rs.close(); }catch(Throwable t){} }
if(ps != null) { try{ ps.close(); }catch(Throwable t){} }
}
return list;
}