为什么 MySQL 数据库 return 清空 ResultSet 尽管数据应该是正确的
Why does MySQL database return empty ResultSet although data should be correct
上下文:
我的数据库中有 2 个不同的 table。第一个是动作块(Java 中的 ActionBlock),第二个是位置(Java 中的 PermanentLocation)。 ActionBlock class 需要一个位置才能工作,因此为了让代码工作,它首先加载包含所需位置的 ActionBlock 数据,然后代码加载必要的位置。 (是的,我知道以下代码将垃圾邮件加载位置查询)
问题:
使用与 ActionBlock 加载器相同的 DB 连接加载位置会给出空的结果集
我试过的:
- 使用不同的连接:没有区别
- 验证密钥是否相同(id 和 uuid):它们是
- 测试数据库中的查询:在 DBMS returns 中创建一个 select 查询 1 个特定行,但将完全相同的查询代码复制到 Java 仍然会导致结果集为空(对于此测试,PreparedStatement 已更改为 Statement)
- 验证我使用的是正确的数据库:操作块从数据库加载正常,我使用相同的连接加载位置
- 代码中的其他连接是否已关闭?:是
- 您的控制台中有哪些错误?:没有错误打印到控制台
"Could not load location" 总是打印到控制台(因为加载程序 returns null)
ActionBlock加载代码
/**
* Loads the blocks from the database. All registerClass calls must be called before this
*/
public void loadBlocksFromDatabase() {
Connection conn = null;
try {
conn = KaranteeniCore.getDatabaseConnector().openConnection();
PreparedStatement stmt = conn.prepareStatement(
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");
stmt.setString(1, KaranteeniCore.getServerIdentificator());
ResultSet set = stmt.executeQuery();
// loop all the blocks from the database
while(set.next()) {
String uuidStr = set.getString(1);
String permission = set.getString(2);
String classType = set.getString(3);
UUID uuid = UUID.fromString(uuidStr);
// check if loaded block is a block or a sign
for(Class<? extends ActionBlock> clazz : subBlockClasses)
if(clazz.getName().equals(classType)) {
// load the location of the block
PermanentLocation loc = PermanentLocation.loadLocation(conn, uuid);
if(loc == null) {
Bukkit.getLogger().log(Level.WARNING, "Could not load location " + uuid.toString() + ". Has it been deleted from database?");
continue;
}
Block block = loc.getLocation().getBlock();
try {
// try to create a new class out of this block
if(permission != null) {
Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
aBlock.onLoad();
registerBlock(aBlock); // register created class
} else {
Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class);
ActionBlock aBlock = cstr.newInstance(block, uuid);
aBlock.onLoad();
registerBlock(aBlock); // register created class
}
} catch (Exception e) {
e.printStackTrace();
}
}
// load all signs
for(Class<? extends ActionSign> clazz : subSignClasses)
if(clazz.getName().equals(classType)) {
// load the location of the block
Block block = PermanentLocation.loadLocation(uuid).getLocation().getBlock();
try {
// try to create a new class out of this block
if(permission != null) {
Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
aBlock.onLoad();
registerBlock(aBlock); // register created class
} else {
Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class);
ActionBlock aBlock = cstr.newInstance(block, uuid);
aBlock.onLoad();
registerBlock(aBlock); // register created class
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch(SQLException e) {
e.printStackTrace();
// ignored
} finally {
try {
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
PermanentLocation 加载代码
/**
* Loads a permanent location from database using the given uuid
* @param conn Connection to the database
* @param uuid uuid of the location
* @return location loaded or null if none found
*/
public static PermanentLocation loadLocation(Connection conn, UUID uuid) {
PermanentLocation location = null;
try {
PreparedStatement st = conn.prepareStatement("SELECT world, x, y, z, pitch, yaw FROM location WHERE id = ? AND serverID = ?;");
st.setString(1, uuid.toString());
st.setString(2, KaranteeniPlugin.getServerIdentificator());
ResultSet set = st.executeQuery();
if(set.next()) {
String w = set.getString(1);
double x = set.getDouble(2);
double y = set.getDouble(3);
double z = set.getDouble(4);
float pitch = set.getFloat(5);
float yaw = set.getFloat(6);
World world = Bukkit.getWorld(w);
if(world == null)
return null;
else
Bukkit.getLogger().log(Level.SEVERE, "Could not find world " + w);
Location loc = new Location(world, x,y,z,pitch,yaw);
location = new PermanentLocation(uuid, loc);
}
else
location = null;
} catch(SQLException e) {
Bukkit.getLogger().log(Level.SEVERE, e.getMessage());
}
return location;
}
sys.statements_with_errors_or_warnings(插入actionblock的是indev代码,有点小错误)
查询来自(我假设)Java
来自位置 table 的内容
动作块中的内容table
需要更多信息?此 post 源自 Spigot forum post
编辑:
重启数据库或系统不影响结果
我想问题出在类型上,请更改行
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");
和
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?");
希望我能帮到你;
找到答案:服务器启动时无法加载位置,因为其他 类 只能在完全启动后才能找到必要的信息(世界)。
上下文: 我的数据库中有 2 个不同的 table。第一个是动作块(Java 中的 ActionBlock),第二个是位置(Java 中的 PermanentLocation)。 ActionBlock class 需要一个位置才能工作,因此为了让代码工作,它首先加载包含所需位置的 ActionBlock 数据,然后代码加载必要的位置。 (是的,我知道以下代码将垃圾邮件加载位置查询)
问题: 使用与 ActionBlock 加载器相同的 DB 连接加载位置会给出空的结果集
我试过的:
- 使用不同的连接:没有区别
- 验证密钥是否相同(id 和 uuid):它们是
- 测试数据库中的查询:在 DBMS returns 中创建一个 select 查询 1 个特定行,但将完全相同的查询代码复制到 Java 仍然会导致结果集为空(对于此测试,PreparedStatement 已更改为 Statement)
- 验证我使用的是正确的数据库:操作块从数据库加载正常,我使用相同的连接加载位置
- 代码中的其他连接是否已关闭?:是
- 您的控制台中有哪些错误?:没有错误打印到控制台
"Could not load location" 总是打印到控制台(因为加载程序 returns null) ActionBlock加载代码
/**
* Loads the blocks from the database. All registerClass calls must be called before this
*/
public void loadBlocksFromDatabase() {
Connection conn = null;
try {
conn = KaranteeniCore.getDatabaseConnector().openConnection();
PreparedStatement stmt = conn.prepareStatement(
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");
stmt.setString(1, KaranteeniCore.getServerIdentificator());
ResultSet set = stmt.executeQuery();
// loop all the blocks from the database
while(set.next()) {
String uuidStr = set.getString(1);
String permission = set.getString(2);
String classType = set.getString(3);
UUID uuid = UUID.fromString(uuidStr);
// check if loaded block is a block or a sign
for(Class<? extends ActionBlock> clazz : subBlockClasses)
if(clazz.getName().equals(classType)) {
// load the location of the block
PermanentLocation loc = PermanentLocation.loadLocation(conn, uuid);
if(loc == null) {
Bukkit.getLogger().log(Level.WARNING, "Could not load location " + uuid.toString() + ". Has it been deleted from database?");
continue;
}
Block block = loc.getLocation().getBlock();
try {
// try to create a new class out of this block
if(permission != null) {
Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
aBlock.onLoad();
registerBlock(aBlock); // register created class
} else {
Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class);
ActionBlock aBlock = cstr.newInstance(block, uuid);
aBlock.onLoad();
registerBlock(aBlock); // register created class
}
} catch (Exception e) {
e.printStackTrace();
}
}
// load all signs
for(Class<? extends ActionSign> clazz : subSignClasses)
if(clazz.getName().equals(classType)) {
// load the location of the block
Block block = PermanentLocation.loadLocation(uuid).getLocation().getBlock();
try {
// try to create a new class out of this block
if(permission != null) {
Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
aBlock.onLoad();
registerBlock(aBlock); // register created class
} else {
Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class);
ActionBlock aBlock = cstr.newInstance(block, uuid);
aBlock.onLoad();
registerBlock(aBlock); // register created class
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch(SQLException e) {
e.printStackTrace();
// ignored
} finally {
try {
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
PermanentLocation 加载代码
/**
* Loads a permanent location from database using the given uuid
* @param conn Connection to the database
* @param uuid uuid of the location
* @return location loaded or null if none found
*/
public static PermanentLocation loadLocation(Connection conn, UUID uuid) {
PermanentLocation location = null;
try {
PreparedStatement st = conn.prepareStatement("SELECT world, x, y, z, pitch, yaw FROM location WHERE id = ? AND serverID = ?;");
st.setString(1, uuid.toString());
st.setString(2, KaranteeniPlugin.getServerIdentificator());
ResultSet set = st.executeQuery();
if(set.next()) {
String w = set.getString(1);
double x = set.getDouble(2);
double y = set.getDouble(3);
double z = set.getDouble(4);
float pitch = set.getFloat(5);
float yaw = set.getFloat(6);
World world = Bukkit.getWorld(w);
if(world == null)
return null;
else
Bukkit.getLogger().log(Level.SEVERE, "Could not find world " + w);
Location loc = new Location(world, x,y,z,pitch,yaw);
location = new PermanentLocation(uuid, loc);
}
else
location = null;
} catch(SQLException e) {
Bukkit.getLogger().log(Level.SEVERE, e.getMessage());
}
return location;
}
sys.statements_with_errors_or_warnings(插入actionblock的是indev代码,有点小错误)
查询来自(我假设)Java
来自位置 table 的内容
动作块中的内容table
需要更多信息?此 post 源自 Spigot forum post
编辑: 重启数据库或系统不影响结果
我想问题出在类型上,请更改行
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");
和
"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?");
希望我能帮到你;
找到答案:服务器启动时无法加载位置,因为其他 类 只能在完全启动后才能找到必要的信息(世界)。