[개발일지] 230502 flatMap과 동적쿼리 foreach문

오늘 새로 배운 내용

flatMap

기존 Redis에서 가져온 데이터와 DB에서 가져온 데이터를 새로운 Response 객체를 만들어서 Service에서 조합해서 응답하는 방식으로 설계했었는데 응답값을 조합하는 방식이 복잡해져 Service가 배보다 배꼽이 커지는 상황이 발생했다. 그래서 Service에서 조합하는것이 아닌 새로운 Response 객체를 만들어서 그 객체안에서 조합해서 응답하는 방식으로 변경하는게 좋겠다는 리뷰를 받았다. 

 

객체들을 조합할 때 처음으로 stream의 flatMap 메서드를 사용해봤는데 각 요소를 인자로 변환하는 map메서드와 다르게 flatMap은 각각의 요소를 다른 스트림으로 변환하는 기능이였다. 

 

flatMap 예시

List<String> words = Arrays.asList("FLAT", "MAP");

List<String> letters = words.stream()
        .map(String::toLowerCase) // 문자열을 소문자로 변환
        .flatMap(str -> Arrays.stream(str.split(""))) // 문자열을 문자별로 분할하고, 이를 단일 스트림으로 평탄화
        .collect(Collectors.toList());

System.out.println(letters); // [f, l, a, t, m, a, p]

 

 

동적 쿼리 (foreach문)

코드리뷰중 List에 담겨진 유니크한 id값을 이용해 특정 데이터를 DB에서 가져오기 위해 반복문을 돌면서 여러번 쿼리를 날리는것보다 식별자를 List형태로 파라미터로 전달해 foreach문을 이용해 동적 쿼리를 작성하는것이 더 효율적이라는 리뷰를 받았다.

 

foreach문을 이용하면 List의 size만큼 반복해서 접근했던 DB에 접근하는 횟수를 1번으로 줄일 수 있고 쿼리 또한 유연하게 작성이 가능하다.

 

myBatis를 이용해 동적 쿼리를 작성하면서 쿼리가 복잡해질 수록 서비스단의 코드가 간단해지는 경우가 있었다.

예를 들어 이전의 나는 여러 entity를 찾아 하나의 객체로 응답해야 하는 상황이 있으면 여러번 쿼리를 날려 조합하는 방식을 택했었는데 동적쿼리를 작성하니 하나의 쿼리(join몇번 하니..)로 가져오는 신기한 경험을 했다. 

 

아직은 쿼리를 잘 작성하지는 못해서 시간을 많이 소비하는데 쿼리 작성할일이 많으니 걱정하지 말라고 해주셨다.. 

 

고민한 내용

특정 기능에 대한 권한이 있는지 체크하는 사용자에 대한 인증 처리는 어떤 Layer에서 해야할지?

-> Presentation Layer(Controller)와 Application Layer(Service) 둘 중 고민을 하다 사용자의 권한에 따라 호출하는 메서드가 달랐기 때문에  Presentation Layer에서 인증하는것이 맞지 않을까? 생각을 했다.

이 부분은 아직 확실치 않아 좀 더 고민해보고 물어봐야 하는 부분이다.