오늘 한 것 + 오늘 배운 것
1. 중복 값 접근 방식에 대해서 조금 더 생각해 봤다.
- DB 조회 후 처리: 값을 넣기 전에 미리 중복 체크를 해서 중복값이 없을 때에만 값을 넣기
- 예외 처리 후 처리: 사용자 번호를 DB에 넣으려고 먼저 시도한 다음에 DataIntegrityViolationException 에러 발생하면 예외 처리
1번은 중복된 번호가 적고 DB의 조회의 성능이 빠를 때, 2번은 DB에 값이 많고 쿼리 성능이 느릴 때 사용하기 좋은 방법 같다는 생각이 들었다.
프로젝트에서는 AWS RDS (MySQL)을 사용하고 있기 때문에 조회 성능이 빠르다. 그리고 핸드폰 번호도 다양한 국가의 번호가 입력되기 때문에 중복 값이 적을 거다. 이 말인즉, 예외 처리 후 처리를 하기보다는 DB 조회 후 처리로 방식을 바꾸는 게 더 나은 접근 방법 같다는 결론이 나왔다.
어제까지만 해도 2번 방식으로 접근하고 있었는데 1번 방식으로 코드를 수정했다.
여기서 배운 것!
👉 DB 조회 후 리턴 값을 Service에서는 boolean, Repository에서는 int로 지정하면 더욱 직관적이다.
public boolean isPhoneNumberAlreadyExists(String phoneNumber) {
return userRepository.countByPhoneNumber(phoneNumber) > 0;
}
int countByPhoneNumber(String phoneNumber);
inPhoneNumber... 메서드의 목적은 전화번호가 몇 개 있는지 확인하는 게 아니다. 이미 존재하는지 여부, 즉 true와 false를 확인하는 거다. 그렇기 때문에 이미 존재하는지 아닌지 boolean을 반환하는 게 더 직관적이다.
👉 count문은 JPA에서 메소드 이름을 통해 기본적인 쿼리를 생성할 수 있다.
2. 전화번호 중복 검사 실행 위치는?
전화번호 인증을 처리하는 메서드는 두 개다.
- 전화번호를 입력받아서 인증 코드를 생성하는 메서드
- 전화번호와 인증 코드를 입력받아서 인증하는 메서드
전화번호 입력 -> 인증 번호 생성 -> 고객이 인증번호를 입력 -> (여기에서 전화번호가 이미 존재하는지 검사하고!) -> 인증 번호를 검증
위 순서로 진행했는데 생각해 보니 1번 메서드에서 하는 게 맞지 않나 싶은 생각이 들었다.
인증 번호를 생성하고 전송하는 과정에서 통신 비용이 든다. 중복된 번호라면 어차피 DB에 넣지 못하는 값인데 왜 불필요하게 인증 번호를 전송하고, 사용자는 그 번호를 다시 입력하는 불필요한 과정을 거쳐야 하는가. 그러므로 최대한 빠르게 중복 전화번호를 찾아내서 사용자에게 알려주는 게 좋지 않을까?
그래서 1번 메서드에서 중복 검사를 실행하도록 했다. 만약에 이미 있는 번호라면 안내문이 나온다.
하지만 여기서 또 생겨버린 고민!!!
1번 위치에서 전화번호 중복 검사를 하면, 악의적인 의도를 가진 사용자가 전화번호를 하나하나 다 넣어봐서 우리 DB에 어떤 값이 있는지 체크해 볼 수 있게 되지 않나?
조금 더 알아봐야겠다...