-2

我想将保存在 MySql DB 中的整数转换为 Java 中的 Integer。我有一个表,其中包括 PlayerName 和 Level。我想从特定玩家那里获得关卡(整数)。然后将整数“值”添加到它。然后将其放回数据库中。到目前为止,我的代码是:

public void addinputPData(String loc, int value, Player player, String playername){
    //add input Player Data
    try{
        logm("Putting Kill Death Int Data into  " +player.getName() + "'s Profile!");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/WebCom", "root", "MyPW");

            int ovalue = -1;    
        Statement stmt = (Statement) con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT "+loc+" FROM PlayerData WHERE PlayerName='"+playername+"'");
        if(rs.next()){
            ovalue= rs.getInt(loc);
        }
        if(ovalue == -1){
            logm("Error Occured");

        }
        int nvalue = value + ovalue;

        String insert = "UPDATE PlayerData SET "+ loc + "='" + nvalue + "' WHERE PlayerName='" + playername + "'";

        stmt.executeUpdate(insert);

        con.close();

    }catch(Exception e){

        logm("Could Not Send Data To MYSQL DATABASE SERVER s: "+ e.getMessage());
    }
}

我不知道为什么这不起作用,我有什么明显的遗漏吗?先感谢您。

4

2 回答 2

1

所以首先你必须明白的是,当你不使用时parametrized statements,会有很大的危险SQL Injection。所以你的代码写得很脏。所以无论如何,使用PreparedStatement参数的 SQL 语句可以获得更好的性能。现在像这样重写你的代码:

final String SELECT_QUERY = "SELECT level FROM PlayerData WHERE PlayerName = ?";
final String UPDATE_QUERY = "UPDATE PlayerData SET level = ? WHERE PlayerName = ?";

public boolean dataMethod(String playerName) {
   Connection con = null;
   PreparedStatement ps = null;
   PreparedStatement ps1 = null;
   ResultSet rs = null;
   int dataLevel = 0;

   try {

   // getConnection etc...
   ps = con.prepareStatement(SELECT_QUERY);
   ps.setString(1, playerName) // first param is order of ? param, starts with 1(not 0)
   rs = ps.executeQuery();
   while (rs.next()) {
      dataLevel = rs.getInt();
   }
   if (dataLevel > 0) {
       ps1 = con.prepareStatement(UPDATE_QUERY);
       ps1.setInt(1, dataLevel);
       ps1.setString(2, playerName);
       ps1.executeUpdate();   
   }
   return true;
   }
   catch (SQLExcetion ex) {
      Logger.getLogger(YourClass.class.getName()).log(Level.SEVERE, null, ex);
      return false;
   }
   finally {
      if (con != null) {
         con.close();
      }
   }
}

一步一步,首先初始化你的语句,如果你有设置参数,那么当你使用 select 时,你将在ResultSet查询生成的数据表中检索数据。隐式光标在ResultSet第一行之前的位置,因此您必须使用next()方法进入当前行,并在 getter 方法的帮助下将数据添加ResultSet到变量中。然后检查它是否正确,如果正确,则初始化第二条语句并执行它。就这样。

但是您应该考虑当您使用超过 1 个操作时,设置autoCommit为 false 并且所有操作都将在 one 中完成Transaction,因为隐含地JDBC是一个操作 = 一个事务。其次,您应该考虑使用SQL 存储过程来添加任何数据、更新数据或删除。它更安全,代码更少。所以让数据库在它能够做到的时候工作,当然它也更快。最后,你真的应该考虑这种方法,让你的代码更安全、更快、更干净。不看简单,而是看效率、兼容性和安全性。

更多关于SQL 注入

当您决定使用存储过程时,您可以像这样使用它:

CREATE OR REPLACE PROCEDURE SOME_NAME(VARCHAR v_name PlayerData.name%type)
AS
BEGIN
   SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
   // body
   COMMIT;
EXCEPTION
   WHEN OTHERS THEN
      ROLLBACK;
END;

所以现在你必须为调用过程创建字符串。

final String CALL_SOMENAME = "{call SOME_NAME(?)}";

然后PreparedStatement你必须使用CallableStatement那个interface用来执行 SQL 存储过程的东西。

cs.prepareCall(CALL_SOMENAME); // Creates a cs object for calling db stored procedures
cs.setString(1, playerName);
cs.execute();

我不知道为什么很多人在寻找最简单的方法来做某事而不看代码的性能和可读性。

问候

于 2012-06-01T18:17:26.127 回答
0

在 UPDATE 语句中,您将“loc”列的值作为字符串插入(值周围有单引号)。如果数据库列是整数,那么这可能会导致问题。

提示: JDBC 提供了一个名为PreparedStatement. 此类允许您安全地构建 SQL 查询。它确保所有用户输入都被正确转义,以避免安全漏洞。

PreparedStatement ps = con.prepareStatement("UPDATE PlayerData SET " + loc + " = ? WHERE PlayerName = ?");
ps.setInt(1, nvalue);
ps.setString(2, playername);
ps.execute();
于 2012-06-01T17:52:13.347 回答