지난 포스팅에서 자바 예외처리에 대해 알아보았다. 이번 포스팅에서는 인터페이스 활용에 있어서 체크 예외와 언체크 예외에 따라 어떻게 바뀌는지 알아보고자 한다.
public interface MemberRepositoryEx {
Member save(Member member) throws SQLException;
Member findById(String memberId) throws SQLException;
void update(String memberId, int money) throws SQLException;
void delete(String memberId) throws SQLException;
}
/*생략*/
public Member save(Member member) throws SQLException {
String sql = "insert into member(member_id, money) values (?,?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.execute();
return member;
} catch (SQLException e) {
log.error("db error", e);
throw e;
}finally {
close(con, pstmt, null);
}
}
/*생략*/
그렇다면 Repository를 활용하는 Service는 어떨까?
@Slf4j
public class MemberServiceV3_3 {
/*생략*/
private void bizLogic(String fromId, String toId, int money) throws SQLException {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
validation(toMember);
memberRepository.update(toId, toMember.getMoney() + money);
}
}
체크 예외의 경우 일종의 표준인 인터페이스가 특정 기술에 종속되어 있다. 만약 JDBC가 아닌 다른 기술을 사용하게 된다면 인터페이스 자체를 바꿔야 하는 문제가 생긴다.
특히 순수 자바 코드를 유지해야할 서비스가 특정 기술에 종속된다는 문제가 있다.
그렇다면 런타임 예외의 경우에는 어떨까?
먼저 서비스를 순수 자바 코드로 구축할 수 있다.
또 인터페이스에 예외를 선언하지 않아도 된다. 따라서 인터페이스가 특정 기술에 종속되지 않는다.
코드로 확인해보자.
public interface MemberRepository {
Member save(Member member);
Member findById(String memberId);
void update(String memberId, int money);
void delete(String memberId);
}
public class MyDbException extends RuntimeException{
public MyDbException() {
}
public MyDbException(String message) {
super(message);
}
public MyDbException(String message, Throwable cause) {
super(message, cause);
}
public MyDbException(Throwable cause) {
super(cause);
}
}
/*생략*/
@Override
public Member save(Member member) {
String sql = "insert into member(member_id, money) values (?,?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.execute();
return member;
} catch (SQLException e) {
throw new MyDbException(e);
}finally {
close(con, pstmt, null);
}
}
/*생략*/
그럼 서비스 로직은 어떻게 되어 있을까?
@Slf4j
public class MemberServiceV4 {
/*생략*/
private void bizLogic(String fromId, String toId, int money) {
Member fromMember = memberRepository.findById(fromId);
Member toMember = memberRepository.findById(toId);
memberRepository.update(fromId, fromMember.getMoney() - money);
validation(toMember);
memberRepository.update(toId, toMember.getMoney() + money);
}
}
그런데 만약 특정 상황에서 예외를 잡아서 다른 처리를 하고 싶다면 예외를 어떻게 구분하고, 또 각 예외에 따라 처리를 할 수 있을까?
이번 포스팅에서는 스프링에서 예외의 종류에 따라 코드가 어떻게 변하게 되는지 알아보았다. 다음 포스팅에서는 각 예외를 구분하여 처리하는 방법과, 거기서 발생하는 문제에 대해서 알아보도록 하자.