我目前正在编写一个MySQL插件,并希望在第二行具有特殊值的第一行读出我的数据库:
private String ip;
public MySqlNPCData(String host, int port){
this.ip = host + ":" + port;
}
public List<UUID> getUUIDs(){
try {
PreparedStatement ps = MySQL.getConnection().prepareStatement("SELECT UUID FROM npc_data WHERE IP = ?");
ps.setString(1, ip);
ResultSet rs = ps.executeQuery();
ArrayList<UUID> IDs = new ArrayList<>();
if(!rs.next()) {
rs.close();
return null;
}
while(rs.next()) {
IDs.add(UUID.fromString(rs.getString("UUID")));
}
for(UUID s : IDs){
System.out.println(s.toString());
}
return IDs;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public boolean contains(NPC npc){
try {
PreparedStatement ps = MySQL.getConnection().prepareStatement("SELECT IP FROM npc_data WHERE UUID = ?;");
ps.setString(1, npc.UID.toString());
ResultSet rs = ps.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
@SuppressWarnings("static-access")
public void save(NPC npc){
if(!contains(npc)){
try {
PreparedStatement ps = MySQL.getConnection().prepareStatement("INSERT INTO npc_data (UUID,IP,WORLD,X,Y,Z,YAW,PITCH,SKIN_UUID) "
+ "VALUES (?,?,?,?,?,?,?,?,?);");
ps.setString(1, npc.UID.toString());
ps.setString(2, ip);
ps.setString(3, npc.getLocation().getWorld().getName());
ps.setDouble(4, npc.getLocation().getX());
ps.setDouble(5, npc.getLocation().getY());
ps.setDouble(6, npc.getLocation().getZ());
ps.setFloat(7, npc.getLocation().getYaw());
ps.setFloat(8, npc.getLocation().getPitch());
ps.setString(9, npc.uuid);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}else{
try {
PreparedStatement ps = MySQL.getConnection().prepareStatement("UPDATE npc_data SET IP = ?, WORLD = ?, "
+ "X = ?, Y = ?, Z = ?, YAW = ?, PITCH = ?, SKIN_UUID = ? WHERE UUID = ?;");
ps.setString(1, npc.UID.toString());
ps.setString(2, ip);
ps.setString(3, npc.getLocation().getWorld().getName());
ps.setDouble(4, npc.getLocation().getX());
ps.setDouble(5, npc.getLocation().getY());
ps.setDouble(6, npc.getLocation().getZ());
ps.setFloat(7, npc.getLocation().getYaw());
ps.setFloat(8, npc.getLocation().getPitch());
ps.setString(9, npc.uuid);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
不幸的是,它总是在系统输出中没有返回任何内容,有人可以帮助我吗?非常感谢你
答案 0 :(得分:1)
一些评论:
使用JDBC时,容器会为您完成一些工作,但不是很多。所以你必须考虑到这一点。
1)块:
if(!rs.next()) {
rs.close();
return null;
}
不需要:如果没有数据,rs.next
将返回false。
2)检索连接的样式最有可能导致不关闭连接:
MySQL.getConnection()
为您提供连接,但未明确关闭。在(例如)Tomcat中,这大部分时间导致MySQL上的最大连接使用,然后是Java中的异常,因为不能打开新的连接。更好的方式是打开连接,并显式关闭它,以及所有其他JDBC连接资源:
Connection conn=MySQL.getConnection();
ResultSet rs=null;
PreparedStatement ps=null;
try {
... All you database actions
} finally {
try { if(ps!=null) ps.close(); } catch(Exception exp) {}
try { if(rs!=null) rs.close(); } catch(Exception exp) {}
try { conn.close(); } catch(Exception exp) {}
}
你当然可以将它包装到你正在使用的MySQL类中,这样你就不必在任何地方写这个。
3)这也意味着代码:
public boolean contains(NPC npc){
try {
PreparedStatement ps = MySQL.getConnection().prepareStatement("SELECT IP FROM npc_data WHERE UUID = ?;");
ps.setString(1, npc.UID.toString());
ResultSet rs = ps.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
必须将重写为不返回rs.next()
,而是返回显式对象:
public boolean contains(NPC npc){
Connection conn=MySQL.getConnection();
PreparedStatement ps=null;
ResultSet rs=null;
boolean retVal=false;
try {
ps = conn.prepareStatement("SELECT IP FROM npc_data WHERE UUID = ?");
ps.setString(1, npc.UID.toString());
rs = ps.executeQuery();
retVal=rs.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try { if(ps!=null) ps.close(); } catch(Exception exp) {}
try { if(rs!=null) rs.close(); } catch(Exception exp) {}
try { conn.close(); } catch(Exception exp) {}
}
return retVal;
}
请注意从;
声明中删除SELECT
:
原始代码:
"SELECT IP FROM npc_data WHERE UUID = ?;"
应该是:
"SELECT IP FROM npc_data WHERE UUID = ?"
;
可以指示多个语句,并且可以导致没有返回值。
您的代码需要做更多的工作,但我认为您明白这一点。