2017-12-30 50 views
0

난 그냥 두 개의 열이 포스트 그레스 테이블 "계정"의 값을 업데이트하는 DAO의 메소드를 작성하는 것을 시도하고있다 : "ID"문자열 "균형"자바 DAO 업데이트 쿼리 실패

public Account setAccountBalance(String id, Integer balance) { 
    Handle h = dbi.open(); 

    try{ 
     return h.createQuery("UPDATE accounts SET balance=" + balance.intValue() + 
          " WHERE id=\'" + id +"\';") 
       .mapTo(Account.class) 
       .first(); 
    } finally { 
     h.close(); 
    } 
} 

을 int로하지만에 I을 실행 다음 예외를 참조하십시오. org.skife.jdbi.v2.exceptions.NoResultsException : 쿼리에 결과 세트가 없습니다. 아마도 업데이트를 의미할까요? [UPDATE 계정 SET 균형 = 20 WHERE id = '1'; ", 다시 작성 :"UPDATE 계정 SET 균형 = 20 WHERE id = 'WHERE ID ='1 '; "

문제가 쿼리 구문 또는 DAO에서 사용되는 경우 어떤 아이디어가 필요하십니까?

+0

쿼리 문자열에서 세미콜론을 제거해볼 수 있습니다. 그리고 쿼리 매개 변수의 문자열 연결 대신 준비된 문을 사용해야합니다. –

+0

또한, 일반적으로 (JDBC 드라이버에 따라) 결과 세트가없는 UPDATE SQL이 있습니다. 업데이트에 잘못된 API 메소드 ('createQuery()')를 사용하고있을 가능성이 있습니다. –

+0

또한 준비된 문에 대해 알아보십시오. 귀하의 코드는 SQL 삽입에 취약하며 ID 이베지에 견적이 포함되어 있으면 실패합니다. –

답변

0

JDBI처럼 보입니다. 설명서에 따르면, 다음과 같은 SQL 업데이트, Handle.execute() 통해 수행 될 수있다 :

h.execute("UPDATE accounts SET balance=? WHERE id=?", balance.intValue(), id); 

을하지만 실행 방법은 Account 객체를 만드는 데 사용할 수 있으므로 설정 결과를 반환하지 않는다.

return h.createQuery("SELECT id, balance FROM accounts WHERE id = :id") 
      .bind("id", id) 
      .mapTo(Account.class) 
      .first(); 
+0

그게 가장 간단한 해결책입니다. 고마워 믹. – vic

+0

여러 대의 클라이언트와 하나의 데이터베이스에서 작동합니까? – vic

+0

네,하지만 건물을 짓는다면 예. 진짜 은행 업무 응용 프로그램이라면 트랜잭션과 격리 수준에 관한 더 큰 그림을 고려해야합니다 (https://en.m.wikipedia.org/wiki/Isolation_ (database_systems) #Isolation_levels). 예를 들어, 계정 잔액을 설정하면 다른 클라이언트가 동시에 동일한 계정을 수정할 수 없도록해야합니다. 이를 달성하는 한 가지 방법은 업데이트 이전에 테이블 행에 _lock_을 획득하는 것입니다 (예 : SELECT FOR UPDATE SQL 절을 통해. 그러나이 주제는 원래 질문의 범위를 벗어납니다. –