본문 바로가기
개발 관련 학습 및 문제해결

ManyToOne, OneToMany 를 쓰지않고 DTO에 List 속성 넣어주기[20221102 TIL]

by 날파리1 2022. 11. 2.

어제 불과 ManyToOne, OneToMany 어노테이션으로 프론트엔드로 보내주는 DTO에 리스트 배열을 넣을 수 있다고 했는데 

오늘은 반대의 방식을 들고 왔다.

오늘 트레이너님께서 위 어노테이션을 사용하면 n + 1 문제 가 생긴다고 해서  나중에 JPA에서 처리해주어야하는 법을 추가로 배워야한다고 했다. 근데 강의에서 배운대로하면 상관없다고 해서 다시..... 지웠다...(동료가 지우라고했는데 고집고집 부리다  테스트 코드 짜기 어려워서 지웠다..)

 

개요

나는 스터디라는 모임을 모으는 게시물 객체가 복수의 해쉬태그의 객체를 가지는 것을 만들고 싶었다. 그래서 List<List<HashTagDto>> 가 등장하면서 너무 헷갈렸는데

 

일단 작게 나눈다.

Study 라는 클래스의 객체를 study.toDto()라는 메소드로 변환해주고 있었다. 이때 study 클래스는 해쉬태그를 가지게 하지 않고 해쉬태그는 독립적으로 모델과 레포지토리를 만들어 study.Dto()에 매개변수로 디티오로 변환시켜서 넣어서 포함시켰다.

 

public StudyDto toDto(List<HashTagDto> hashTags) {
  String registrationDate = createdAt == null ? "" : createdAt.toLocalDate().toString();

  return new StudyDto(
      id,
      writer,
      title,
      topic,
      place,
      time,
      participants,
      content,
      views,
      likes,
      registrationDate,
      hashTags
  );
}

그러면 일단 스터디디티오가 복수의 해쉬태그를 가지고 있다.

 

복수가 될 모델의 서비스(해쉬태그 서비스)

@Service
@Transactional
public class HashTagService {
  public HashTagService(HashTagRepository hashTagRepository) {
    this.hashTagRepository = hashTagRepository;
  }

  private HashTagRepository hashTagRepository;
  public List<HashTagDto> list(Long studyId) {

    return hashTagRepository.findAllByStudyId(studyId)
        .stream().map(HashTag::toDto)
        .collect(Collectors.toList());
  }
}

해쉬태그는 각각 포함되는 모델의 아이디를 가지고 있고 그것을 찾아와서 만들어지는 리스트를 Dto 로 변환해준다.

그럼 1차로 복수의 List<HashTagDto> 완성

 

스터디 컨트롤러에서 다시 리스트화시키기

 

List<StudyDto> studyDtos =
    studyService.list(page)
        .stream()
        .map(study -> study.toDto(hashTagService.list(study.getId())))
        .collect(Collectors.toList());

int pageNumber = studyService.pages();

return new StudiesDto(studyDtos, pageNumber);
study -> study.toDto(hashTagService.list(study.getId()))

 

다시 맵으로 study를 List<HashTagDto>담은 studyDto로 변환해준다. 이거를 모아서 다시 컬렉션(리스트)화 하면

 

최종적으로 Lists<StudyDto> 가 완성되고 StudyDto는 다시 List<HashTagDto>를 가지고 있다.( 

결국 List<List<HashTagDto>> 구현한샘)

 

다음은 참고가 필요하면 볼 스터디 서비스 코드 ( 페이지네이션 되어있다.)

public Page<Study> list(int page) {

  Sort sort = Sort.by("createdAt").descending();

  pageable = PageRequest.of(page - 1, 4, sort);

  return studyRepository.findAll(pageable);
}

public int pages() {
  return studyRepository.findAll(pageable).getTotalPages();
}

백엔드 서버 송출

조금복잡하지만 스터디즈라는 객체가 하나의 스터디객체를 들고 그 안에 또 해쉬태그 배열이 있는걸 볼 수 있다 그리고 추가로 페이지네이션할 넘버도 들고 있다.

{"studies":
[{"id":1,
"writer":"로지",
"title":"모각코 성수",
"topic":"리액트",
"place":"성수도장",
"time":"매주 월요일 아홉시",
"participants":"2명",
"content":"자바",
"views":23,"
likes":12,
"registrationDate":"2022-10-06",
"hashTags":[{"tag":"자바"},{"tag":"java"}]}],
"pageNumber":1}

 

 

댓글