해당 글은 팀 프로젝트를 진행하면서 맡았던 파트에 대한 내용을 기록하는 용도로 작성되었습니다. 공부를 통해 배운 내용을 응용하고 이와 관련된 문제점을 파악하며 느낀점을 작성하기 위함입니다.
필자는 백엔드에서 DB 및 데이터 접근 계층을 담당하게 되었다. 따라서 데이터 접근 계층에 대한 인터페이스를 정의하고 관련된 메서드를 구현하여 테스트해야 한다.
1. 데이터 접근 인터페이스 정의
서비스 계층이 구현체에 의존하게 되면, 이후 데이터 접근 기술을 변경하였을 때 영향을 받을 수 있다. 따라서 인터페이스와 의존할 수 있도록 데이터 접근 관련 인터페이스를 정의하였다.
public interface QuestionRepository {
public void questionWrongCountRead();
public void questionWrongCountUpdate();
}
@Repository
public class QuestionRepositoryImpl implements QuestionRepository {
@Override
public void questionWrongCountRead() {
}
@Override
public void questionWrongCountUpdate() {
}
}
public interface TotalCountRepository {
public int totalCountRead();
public void totalCountUpdate();
}
@Repository
@RequiredArgsConstructor
public class TotalCountRepositoryImpl implements TotalCountRepository {
private final DataSource dataSource;
@Override
public int totalCountRead() {
String sql = "select * from totalcount";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) {
// 가져온 데이터가 있을 때 실행할 부분
int totalCount = rs.getInt("totalCount");
return totalCount;
} else {
throw new NoSuchElementException("값이 없습니다.");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(pstmt);
JdbcUtils.closeConnection(con);
}
}
@Override
public void totalCountUpdate() {
}
private Connection getConnection() throws SQLException {
Connection con = dataSource.getConnection();
return con;
}
}
2. 순수 JDBC를 통해 DB에 접근
@Repository
@RequiredArgsConstructor
public class TotalCountRepositoryImpl implements TotalCountRepository {
private final DataSource dataSource;
@Override
public int totalCountRead() {
String sql = "select * from totalcount";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
rs = pstmt.executeQuery();
if (rs.next()) {
// 가져온 데이터가 있을 때 실행할 부분
int totalCount = rs.getInt("totalCount");
return totalCount;
} else {
throw new NoSuchElementException("값이 없습니다.");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(pstmt);
JdbcUtils.closeConnection(con);
}
}
@Override
public void totalCountUpdate() {
}
private Connection getConnection() throws SQLException {
Connection con = dataSource.getConnection();
return con;
}
}
- 서비스 계층에서 트랜잭션을 수행할 때, SQLException 같은 여러 JDBC 기술들을 사용하게 된다. 따라서 순수 JDBC로 코드를 짜는 것은 바람직하지 않다.
- 물론 여기서는 체크 예외인 SQLException을 런타임 예외로 처리하였기 때문에 서비스 쪽으로 예외가 넘어가지는 않을 것이다.
- 또한 try-catch-finally가 다른 메서드에서도 반복적으로 쓰일 것이기에 이들을 간편화 하는 방법이 필요하다. (스프링 DB 학습 후 리팩토링 예정