수정 기능
이번엔 글 수정 기능을 구현해 보자.
글을 수정할 때는 원래의 포스팅의 idx값을 그대로 써야 한다는 점을 잊지 말자.
물론, 글을 수정할 떄는 사용자 정보 또한 바뀌면 안되기에 해당 부분을 확인해 주면 더 좋다.
일단 지금은 최소한의 글을 수정하기 위한 기능들만 작성해 보자.
먼저, PostingDAO에서 직접 Connection을 가지고 와 구현을 해 본다.
public void update(Posting posting){
try (Connection conn =
DriverManager.getConnection(url, userName, password)) {
PreparedStatement ps = conn.prepareStatement(
"update posting set title = ?, content = ? where idx = ?");
ps.setString(1, posting.getTitle());
ps.setString(2, posting.getContent());
ps.setString(3, Integer.toString(posting.getIdx()));
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
테스트 코드는 다음과 같이 작성했다.
@Test
public void update() throws Exception{
//given
userDAO.save(user);
postingDAO.save(posting, user);
//when
Posting newPosting = new Posting();
newPosting.setIdx(posting.getIdx());
newPosting.setUser_idx(posting.getUser_idx());
newPosting.setTitle("new Title");
newPosting.setContent("new Content");
postingDAO.update(newPosting);
//then
Posting newPostingByIdx =
postingDAO.findByIdx(posting.getIdx());
isSamePosting(newPostingByIdx, newPosting);
}
public void isSamePosting(Posting a, Posting b)
throws Exception {
Assertions.assertThat(a.getIdx()).isEqualTo(b.getIdx());
Assertions.assertThat(a.getTitle()).isEqualTo(b.getTitle());
Assertions.assertThat(a.getContent()).isEqualTo(b.getContent());
Assertions.assertThat(a.getUser_idx()).isEqualTo(b.getUser_idx());
}
테스트 결과는 성공이다!!
중복 추출
업데이트를 하는 기능 역시 자주 사용될 기능이므로, 추출을 해 두자.
업데이트 메서드의 정의는 다음과 같다.
void update(String sql, String... args);
업데이트에 사용할 SQL과 바인딩할 파라미터들을 순서대로 전달해 주는 것이다.
아래는 문맥의 구현이다.
sql문에 파라미터를 바인딩 시키고, 실행을 하는 로직이 전부이다.
@Override
public void update(String sql, String... args) {
try (Connection conn = getConnect()) {
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setString(i+1, args[i]);
}
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
마지막으로, 간단해진 PostingDAO의 코드이다.
public void update(Posting posting){
String sql = "update posting set title = ?, content = ? where idx = ?";
daoContext.update(sql, posting.getTitle(),
posting.getContent(),
Integer.toString(posting.getIdx()));
}
삭제 기능
삭제 기능도 함께 구현해 보자.
삭제 기능에서 필요한 정보는 인덱스 정보 하나이다.
구현은 아래와 같이 간단하게 된다.
public void delete(int idx) {
try(Connection conn = DriverManager
.getConnection(url, userName, password)) {
PreparedStatement ps = conn.prepareStatement("delete from posting where idx = ?");
ps.setString(1, Integer.toString(idx));
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
그런데, 지금까지의 구현으로는 삭제 기능을 테스트 하기가 애매하다.
데이터가 삭제된 것을 검증하기 위해서는 해당 데이터를 조회하려고 할 때 예외가 발생하거나, 특정 오류 메시지가 출력되는 등의 동작이 필요하다.
그러나, 우리는 아직 조회 기능에서 위와 같은 예외 처리를 해 주지 않았기 떄문이다.
예외 처리
이제, 우리는 없는 데이터를 조회하려 할 때 사용할 Exception을 하나 만들어 사용하자.
public class NoDataFoundedException extends SQLException {}
그리고, DAOContext의 조회 기능을 다음과 같이 수정하자.
@Override
public <R, I> R getObject(String sql,
Function<ResultSet, R> mapper,
I identifier) throws SQLException {
R returnObject = null;
try (Connection conn = getConnect()) {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, identifier.toString());
ResultSet rs = ps.executeQuery();
if (rs.next()) {
returnObject = mapper.apply(rs);
} //예외 처리 추가
else{
throw new NoDataFoundedException();
}
}
//SQLException을 클래스 밖으로 던져 외부에서 처리
/*catch (SQLException e) {
e.printStackTrace();
}*/
return returnObject;
}
이제 getObject() 메서드는NoDataFoundedException를 포함한 SQLException을 밖으로 던질 것이다.
이제 getObject() 메서드를 사용하는 다른 메서드 역시 해당 예외를 처리하거나, 예외를 다시 밖으로 던져 주어야 한다.
public Posting findByIdx(int idx) throws SQLException {
//...
findByIdx() 메서드도 다시 밖으로 SQLException을 던지도록 하자.
마지막으로, 테스트 코드를 다음과 같이 작성한다.
@Test
public void delete() throws Exception{
//given
userDAO.save(user);
postingDAO.save(posting, user);
//when
postingDAO.delete(posting.getIdx());
//then
Assertions.assertThatThrownBy(() ->
postingDAO.findByIdx(posting.getIdx()))
.isInstanceOf(NoDataFoundedException.class);
}
delete() 메서드로 데이터를 삭제한 뒤에 다시 해당 데이터를 조회하려 하면 NoDataFoundexException이 발생하는 것을 확인하는 데이터이다.
테스트 성공이다!!
중복 추출
지금까지 했던 것과 동일하게 진행할 것이다.
간단하게만 설명하고 빠르게 넘어가자.
1. 인터페이스에 메서드 추가하고
public interface DAOInterface {
//...
void delete(String sql, String identifier)
throws SQLException;
}
2. DAOContext에서 구현하고
@Override
public void delete(String sql, String identifier) throws SQLException {
try(Connection conn = getConnect()) {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, identifier);
ps.executeUpdate();
}
}
3. PostingDAO에서 사용하자.
public void delete(int idx) throws SQLException {
String sql = "delete from posting where idx = ?";
daoContext.delete(sql, Integer.toString(idx));
}
테스트 성공!
'프로젝트 > selfmade Blog - V1 (deprecated)' 카테고리의 다른 글
7. MVC 구현 (0) | 2023.08.20 |
---|---|
6. 유저 CRUD 구현 및 테스트 데이터 삭제 (0) | 2023.08.13 |
4. 스프링을 사용한 의존성 주입 (0) | 2023.08.12 |
3. 블로그 글 작성 기능 - 조회 기능 및 중복 Context 추출 (0) | 2023.08.11 |
3. 블로그 글 작성 기능 - 글 생성 및 중복 Context 추출 (1) | 2023.08.11 |
댓글