들어가며
- 저번 포스트에서 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();
}
}
'Spring & JPA > JDBC' 카테고리의 다른 글
JDBC - JDBC 커넥션 풀 - DataSource (0) | 2023.06.05 |
---|---|
JDBC - JDBC 커넥션 풀 - 커넥션 풀의 개념 (0) | 2023.06.05 |
JDBC - JDBC 사용 - 2. 데이터 조회 (0) | 2023.06.03 |
JDBC - JDBC사용 - 1. 데이터 저장 (0) | 2023.06.03 |
JDBC - JDBC의 이해 - 데이터 접근 기술 (0) | 2023.06.03 |