2012-06-01 2 views
-3

MySql DB에 저장된 정수를 Java 정수로 가져오고 싶습니다. 나는 PlayerName과 Level을 포함하는 Table을 가지고있다. 특정 플레이어의 레벨 (정수)을 얻고 싶습니다. 그런 다음 Integer "Value"를 추가하십시오. 그런 다음 DB에 다시 넣으십시오. 내 코드는 최대 이제 :MySQL에서 정수 가져 오기 선택문

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

이 작동하지 않습니다 이유는 나도 몰라, 내가 놓친 게 분명 있나요? 미리 감사드립니다.

+3

정확히 작동하지 않는 기능은 무엇입니까? 예외가 있습니까? 아무 반응이 없습니다? 우리는 더 많은 정보가 필요합니다. – pcalcao

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

단계는, 첫째, 당신의 문을 초기화하기 당신은 당신이 선택 사용할 때 다음, 당신은 쿼리로 생성 된 데이터의 테이블 인 ResultSet에서 데이터를 검색 할 경우 매개 변수를 설정합니다. 즉, ResultSet에있는 커서는 첫 번째 행 앞에 위치하므로 next() 메서드를 사용하여 현재 행을 이동하고 getter 메서드를 사용하여 ResultSet의 데이터를 변수에 추가해야합니다. 그런 다음 올바른지 확인하십시오. 수행 할 경우 두 번째 명령문을 초기화하고 실행하십시오. 그리고 그게 다야.

JDBC에 암시 적으로 하나의 작업 = 하나의 트랜잭션이므로을 false로 설정하고 모든 작업을 하나의 Transaction으로 설정하면 1 작업을 더 많이 사용할 때 고려해야합니다. 그리고 두 번째로, 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; 

그래서 지금 당신은 통화 과정에 대한 문자열을 만들어야합니다.

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

그런 다음 PreparedStatement의 intead 당신은 SQL 저장 프로 시저를 실행하는 interface 사용되는 CallableStatement을 사용해야합니다.

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

나도 몰라 왜 뭔가를 할 수있는 성능과 코드의 가독성에 보이지 않는 가장 쉬운 방법을 검색하는 많은 사람들.

감사합니다.

+0

대단히 감사합니다! 나는 이것을 시도 할 것이다 지금 !!! –

+0

이 코드는 좋은 것으로 보이지만 나는 그것이 내가 의미하는 것이라고 생각하지 않습니다. 이제 상황 : 테이블에 내 데이터베이스와 정수 수준 (변수 loc에 의해 표시됨) 및 String PlayerName에 카운터가 있습니다. 나는 그 메소드가 호출 될 때마다 레벨을 얻고, 1을 더한 다음 다시 DB에 제출하기를 원한다. 그것이 내가 실패하는 곳이다. 어쨌든 도움을 주셔서 감사합니다. 어쩌면 당신도 이것으로 나를 도울 수 있습니다. - Jan –

관련 문제