DevBoi

[JPA] QueryDsl 친구 관련 설계 본문

Develop/[JPA]

[JPA] QueryDsl 친구 관련 설계

HiSmith 2023. 8. 16. 21:47
반응형

친구데이터 관련 설계를 하고 있었다.

뭐가 좋을까. 고민 되었다.

특히 추천 친구라는 기능을 하나 만들고 싶었다. 

우선 Entity간의 연관관계를 두기 싫었다.

 

그래서... 나는 이렇게 설계했다.

회원가입하면, Friends 테이블에 자기 자신도 넣어주는 것이다.

자세한건 아래 로직을 보자

 

1) 회원가입 로직

@PostMapping("/user")
  public User saveUser(@RequestBody UserDto userDto) {
    return userService.saveUser(userDto);
  }
public User saveUser(UserDto userDto) {
    List<User> result = userRepository.findByUserId(userDto.getUserId());
    if(result.size() > 0)
      //정보가 있으면 그냥 그정보를 리턴
      return result.get(0);
    else {
      //회원 가입 로직
      FriendDto myself = FriendDto.myselfFriendDto(userDto);
      friendRepository.save(new Friend(myself));
      return userRepository.save(new User(userDto));
    }
  }

로그인 정보가 있다면, 정보를 주고

그게 아니라면 user,friend에 저장을 해준다. Friend.myself는 source,target 전부 자기자신이고 상태가 30(친구완료)이다.

 

그리고 추천 친구 리스트를 받는 repo부분이다.

@Override
  public List<User> findFriendRecommandList(String userId) {
    //회원의 추천 친구를 리턴해준다.(현재 자신의 친구가 아니여야 한다)
    //요청 한적도 없고, 친구도 아닌 애들을 리턴해준다.
    return queryFactory.select(user)
      .from( friend,user)
      .where(
        friend.sourceId.eq(user.userId),
        friend.sourceId.ne(userId),
        friend.targetId.ne(userId)
        //friend.sourceId.eq(user.userId)
      )
      .stream().toList();
  }

 

사실 대부분 Repo를 별도로 두지 않고, 사용하는 것을 권고하긴 하더라.

근데 나는 repo로 나누는게 보기에도 좋고, 별도로 hibernate에서 자동 지원해주는 것들을 그냥 쓸수 있어서 아직 까진 좋은 것 같다.

너무 단순한 도메인은 바로 service에서 queryfactory를 주입받아서 쓰는 방법도 있고

비즈니스 로직이 복잡하면 booleanExpression 메소드를 사용하는 것도있지만. 다음 포스팅에 정리해보도록 하자.

 

무튼 이렇게 하면,

추천 친구로는 나랑 친구 요청이나 친구상태가 아닌 user리스트들이 조회가 된다.

@Override
  public List<User> findFriendreqList(String userId) {
    return queryFactory.select(user)
      .from(user,friend)
      .where(
        user.userId.eq(friend.targetId)
          .and(user.userId.ne(userId))
          .and(friend.status.eq("10"))
      ).stream().distinct().toList();
  }

 

추가로 위 처럼, 나한테 요청한 상태의 친구를 볼 수도 있고

@Override
  public List<User> findFriendList(String userId) {
    return queryFactory.select(user)
      .from(user,friend)
      .where(
        user.userId.eq(friend.targetId)
          .and(user.userId.ne(userId))
          .and(friend.status.eq("30"))
          .and(friend.targetId.ne(userId))
      ).stream().distinct().toList();
  }

 

이미 친구를 맺은 리스트들을 볼 수도있다.

leftouter 조인이나 세타조인에 대해서 신규 querydsl에서는 많은 지원을 해주는 것 같아서 편하다.

반응형