
데이터 접근 예외 직접 만들기

SQLException 에는 데이터베이스가 제공 하는 errorCode 라는 것이 들어있다.
- 데이터베이스에서 어떤 문제가 발생했는지 확인할 수 있다.
- 오류 코드를 사용할 때는 데이터베이스 메뉴얼을 확인해야 한다.
errorCode를 확인하여 사용하려면 결구 SQLException을 사용해야 한다(의존성 발생)
- 리포지토리에서 예외를 변경하여 던지면 된다
- 스프링에서는 이러한 기능들을 이미 구현하여 지원해줌
예)
@Slf4j
public class ExTranslatorV1Test {
Repository repository;
Service service;
@BeforeEach
void init() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(ConnectionConst.URL, ConnectionConst.USERNAME, ConnectionConst.PASSWORD);
repository = new Repository(dataSource);
service = new Service(repository);
}
@Test
void duplicateKeySave() {
service.create("m1");
service.create("m1");
}
@RequiredArgsConstructor
static class Service {
private final Repository repository;
public void create(String memberId) {
try {
repository.save(new Member(memberId, 0));
log.info("saveId={}", memberId);
} catch(MyDuplicateKeyException e) {
log.info("키 중복, 복구 시도");
String retryId = generateNewId(memberId);
log.info("retryId={}", retryId);
repository.save(new Member(retryId, 0));
} catch (MyDbException e) {
log.info("데이터 접근 계층 예외", e);
}
}
private String generateNewId(String memberId) {
return memberId + new Random().nextInt(10000);
}
}
@RequiredArgsConstructor
static class Repository {
private final DataSource dataSource;
public Member save(Member member) {
String sql = "insert into member(member_id, money) values(?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
con = dataSource.getConnection();
pstmt = con.prepareStatement(sql);
pstmt.setString(1, member.getMemberId());
pstmt.setInt(2, member.getMoney());
pstmt.executeUpdate();
return member;
} catch (SQLException e) {
if (e.getErrorCode() == 23505) {
throw new MyDuplicateKeyException(e);
}
throw new MyDbException(e);
} finally {
closeStatement(pstmt);
closeConnection(con);
}
}
}
}
