从MySQL Select语句获取整数

时间:2012-06-01 16:43:18

标签: java mysql database integer

我想在MySql DB中保存一个整数到Java中的整数。我有一个表,包括PlayerName和Level。我想从特定播放器获得级别(整数)。然后将Integer“Value”添加到其中。然后把它放回DB中。我的代码到目前为止:

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());
    }
}

我不知道为什么这不起作用,有什么明显的我遗失了吗?提前谢谢。

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

首先,您必须了解的是,当您不使用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,所有操作都将在Transaction中进行,因为JDBC中隐含的是一个操作=一个事务。其次,您应该考虑使用 SQL存储过程来添加任何数据,更新数据或删除。它更安全但代码更少。因此,当数据库能够执行时,让数据库工作,当然它也更快。 最后,您应该考虑这种方法,使您的代码更安全,更快速,更清洁。没有看简单,而是效率,兼容性和安全性。

有关SQL Injection

的更多信息

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

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;

所以现在你必须为调用过程创建String。

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();

我不知道为什么很多人会以最简单的方式搜索某些内容而不关注代码的性能和可读性。

此致