들어가며

  • 저번 포스트에서 JDBC를 사용하여 데이터를 조회하는 과정을 구현하였다.
  • 이번 포스트에서는 JDBC를 사용하여 데이터를 수정하는 과정을 구현할 것이다.

 

 

 

데이터의 수정

  • 데이터를 수정하는 SQL은 다음과 같다.
UPDATE MEMBER SET MONEY=? WHERE MEMBER_ID=?
  • 당연하게도 해당 SQL을 DB에 전송하기 위해서는 커넥션과 전송시킬 객체가 필요하다.
  • 이전과 비슷한 코드이기 때문에 별다른 설명 없이 구현한다.
public void update(String memberId, int money) throws SQLExceptions{
    String sql = "update member set money=? where member_id=?";
    
    Connection conn = null;
    PrepareStatement pstmt = null;
    
    try{
        conn = getConnection();
        pstmt = conn.prepareStatement(sql);
        
        pstmt.setInt(1, money);
        pstmt.setString(2, memberId);
        
        pstmt.excuteUpdate();
    } catch(SQLException e){
        throw e;
    } finally{
        close(conn, pstmt, null);
    }
}
  • getConnection()으로 커넥션을 얻고 수정 SQL을 전송하면 끝이다. 이후 커넥션을 종료하고 자원을 반환한다.

 

 

 

데이터의 삭제

  • 데이터의 삭제 SQL은 다음과 같다.
DELETE FROM MEMBER WHERE MEMBER_ID=?
  • 코드는 위의 수정 메서드와 거의 동일하다. 바로 구현해보자.
public void delete(String memberId, int money) throws SQLExceptions{
    String sql = "delete from member where member_id=?";
    
    Connection conn = null;
    PrepareStatement pstmt = null;
    
    try{
        conn = getConnection();
        pstmt = conn.prepareStatement(sql);
        
        pstmt.setString(1, memberId);
        
        pstmt.excuteUpdate();
    } catch(SQLException e){
        throw e;
    } finally{
        close(conn, pstmt, null);
    }
}
  • 수정과 삭제는 생각 외로 간단하고 비슷하다는 것을 알 수 있다.
  • 이제 해당 기능들이 잘 동작하는지 테스트해보자.

 

 

 

기능 테스트

class MemberRepositoryV0Test{
    MemberRepositoryV0 memberRepository = new MemberRepositoryV0();
    
    @Test
    void crud() throws SQLException{
        Member member = new Member("memberA", 10000);
        
        repository.save(member);
        
        Member memberA = repository.findById("memberA");
        Assertions.assertThat(memberA).isEqualTo(member);
        
        repository.update(member.getMemberId(), 12000);
        
        memberA = repository.findById("memberA");
        
        Assertions.assertThat(memberA).isEqualTo(member);
        Assertions.assertThat(memberA.getMoney()).isEqualTo(12000);
        
        repository.delete("memberA");
        Assertions.assertThatThrownBy(() -> repository.findById("memberA"))
                .isInstanceOf(NoSuchElementException.class);
        
    }
}
  • 회원 정보를 저장하고 돈을 수정한 뒤 삭제하고 해당 회원 정보를 다시 찾는 테스트를 수행하였다.
  • 회원 정보가 존재하지 않을 때 NoSuchElementException을 발생시키도록 구현한 것을 기억하자. assertThatThrownBy는 해당 함수를 수행시켰을 때 어떤 예외가 발생되는지를 확인하고 검증한다.
  • 데이터가 삭제되기 때문에 이제 해당 테스트를 반복해서 수행해도 에러가 발생되지 않는다. 지금까지 발생한 에러가 PRIMARY KEY가 동일해서 일어난 에러이기 때문이다.
    • 트랜젝션이란 개념을 적용하면 회원 정보를 삭제하지 않아도 테스트를 반복적으로 수행을 할 수 있다. 이에 대한 설명은 이후에 설명한다.

 

 

 

정리

  • 지금까지 JDBC를 사용하여 회원 데이터를 저장, 조회, 수정, 삭제의 CRUD를 모두 해보았다.
  • 다음 포스트부터는 하나의 요청이 아니라 여러 요청이 동시에 데이터를 저장, 조회, 수정, 삭제를 하나의 데이터에 대해 적용할 때 일어날 수 있는 문제점에 대해 알아보고 그에 대한 해결책을 알아본다.
  • 전체적인 코드는 다음과 같다.
public class MemberRepositoryV0{

    public Member save(Member member) throws SQLException{
        String sql = "insert into member(member_id, money) values(?, ?)";
        
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try{
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setString(1, member.getMemberId());
            pstmt.setInt(2, member.getMoney());
            
            pstmt.excuteUpdate();
            
            return member;
        } catch (SQLException e){
            throw e;
        } finally{
            close(conn, pstmt, null);
        }
    }
    
    public Member findById(String memberId) throws SQLException{

        String sql = "select * from member where member_id=?";

        Connection conn = null;
        PrepareStatement pstmt = null;
        ResultSet rs = null;
    
        try{
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setString(1, memberId);
        
            rs = pstmt.excuteQuery();
        
            if(rs.next()){
                Member member = new Member();
                member.setMemberId(rs.getString("member_id"));
                member.setMoney(rs.getInt("money"));
            } else{
                throw new NoSuchElementException("member not found, memberId = " + memberId);
            }
        
            return member;
        } catch (SQLException e){
            throw e;
        } finally{
            close(conn, pstmt, rs);
        }
    }
    
    public void update(String memberId, int money) throws SQLExceptions{
        String sql = "delete from member where member_id=?";
    
        Connection conn = null;
        PrepareStatement pstmt = null;
    
        try{
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
        
            pstmt.setString(1, memberId);
        
            pstmt.excuteUpdate();
        } catch(SQLException e){
            throw e;
        } finally{
            close(conn, pstmt, null);
        }
    }
    
    public void delete(String memberId, int money) throws SQLExceptions{
        String sql = "delete from member where member_id=?";
    
        Connection conn = null;
        PrepareStatement pstmt = null;
    
        try{
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
        
            pstmt.setString(1, memberId);
        
            pstmt.excuteUpdate();
        } catch(SQLException e){
            throw e;
        } finally{
            close(conn, pstmt, null);
        }
    }

    public void close(Connection conn, Statement stmt, ResultSet rs){
        if(rs != null){
            try{
                rs.close();
            } catch(SQLException e){
               throw e;
            }
        }
        
        if(stmt != null){
            try{
                stmt.close();
            } catch(SQLException e){
               throw e;
            }
        }
        
        if(conn != null){
            try{
                conn.close();
            } catch(SQLException e){
               throw e;
            }
        }
    }
    
    private Connection getConnection(){
        return DBConnectionUtil.getConnection();
    }

}
복사했습니다!