DevBoi

[JPA] 친구 관련 API개발 본문

Develop/[JPA]

[JPA] 친구 관련 API개발

HiSmith 2023. 8. 19. 10:46
반응형

<추천 친구 영역>

추천친구 (나랑 아무런 친구 요청이 없는 것)

친구 요청(추천친구에서 친구 요청)

친구 검색(닉네임 기준 친구 검색)

 

<추천 친구영역 별도 탭>

친구 리스트 (본인과 친구관계인 사람)

 

<마이페이지>

친구 수락(친구 요청에 대한 승인)

친구 요청 내역 확인(본인 기준 친구 요청을 보낸사람)

 

우선 이렇게 3가지에 대한 API를 개발할 것이고, 포스팅은 한개만 예시로 할 것이다.

해당 API는 플러터에서 사용 목적으로 개발한다.

 

친구 controller

@GetMapping("/recommand-friends")
  public List<?> recommandFriends(@RequestParam("userId") String userId) {
    return friendService.recommendFriends(userId);
  }
  @PostMapping("/req-friends")
  public Friend reqFriends(@RequestBody FriendDto friendDto) {
    return friendService.reqFriends(friendDto);
  }

  @GetMapping("/search-friends")
  public List<User> searchFriends(@RequestParam("userId") String userId) {
    return friendService.searchFriends(userId);
  }
  @GetMapping("/friends-list")
  public List<User> findFriendList(@RequestParam("userId") String userId) {
    return friendService.findFriendList(userId);
  }

 

친구 Service

package com.boiler.flutterbackend.app.friend;


import com.boiler.flutterbackend.app.friend.constant.FriendStatus;
import com.boiler.flutterbackend.app.friend.dto.FriendDto;
import com.boiler.flutterbackend.app.friend.entity.Friend;
import com.boiler.flutterbackend.app.friend.repo.FriendRepository;
import com.boiler.flutterbackend.app.user.dto.UserDto;
import com.boiler.flutterbackend.app.user.entity.User;
import com.boiler.flutterbackend.app.user.repo.UserRepository;
import com.querydsl.core.QueryFactory;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

import static com.boiler.flutterbackend.app.friend.entity.QFriend.friend;
import static com.boiler.flutterbackend.app.user.entity.QUser.user;


@Service
@RequiredArgsConstructor
@Transactional
public class FriendService {
  private final FriendRepository friendRepository;
  private final JPAQueryFactory queryFactory;

  public List<User> recommendFriends(String userId){
    return friendRepository.findFriendRecommandList(userId);
  }

  public Friend reqFriends(FriendDto friendDto) {
    friendRepository.save(new Friend(friendDto));
    return friendRepository.save(new Friend(friendDto.reverseFriendDto()));
  }
  public List<User> searchFriends(String userId) {
    return friendRepository.searchFriends(userId);
  }
  public List<User> findFriendList(String userId) {
    return friendRepository.findFriendList(userId);
  }
  public Friend approveFriends(FriendDto friendDto) {
    friendDto.setStatus(FriendStatus.FRIEND.getStatus());
    friendRepository.save(new Friend(friendDto));
    return friendRepository.save(new Friend(friendDto.reverseFriendDto()));
  }



}

 

친구 repo

package com.boiler.flutterbackend.app.friend.repo;

import com.boiler.flutterbackend.app.friend.entity.Friend;
import org.springframework.data.jpa.repository.JpaRepository;

public interface FriendRepository extends JpaRepository<Friend,Long>, FriendCustomRepository {
}
public interface FriendCustomRepository {
  List<User> findFriendRecommandList(String userId);
  List<User> searchFriends(String userId);
  List<User> findFriendList(String userId);
  List<User> findReqFriendList(String userId);

  Long updateFriends(FriendDto friendDto);


  Long deleteFriends(FriendDto friendDto);

}
package com.boiler.flutterbackend.app.friend.repo;

import static com.boiler.flutterbackend.app.user.entity.QUser.user;
import static com.boiler.flutterbackend.app.friend.entity.QFriend.friend;

import com.boiler.flutterbackend.app.friend.constant.FriendStatus;
import com.boiler.flutterbackend.app.friend.dto.FriendDto;
import com.boiler.flutterbackend.app.friend.entity.Friend;
import com.boiler.flutterbackend.app.user.entity.User;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class FriendCustomRepositoryImpl implements FriendCustomRepository{
  private final JPAQueryFactory queryFactory;

  //회원의 추천 친구를 리턴해준다.(현재 자신의 친구가 아니여야 한다)
  //요청 한적도 없고, 친구도 아닌 애들을 리턴해준다.
  @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)
      )
      .stream().toList();
  }
  //친구 검색 - like 조건 유저 검색
  @Override
  public List<User> searchFriends(String userId) {
    return queryFactory.select(user)
      .from(user)
      .where(
        user.userId.contains(user.userId)
      ).stream().toList();
  }
  //친구 요청 검색 - 나에게 요청온 친구 리스트 검색
  @Override
  public List<User> findReqFriendList(String userId) {
    return queryFactory.select(user)
      .from(user,friend)
      .where(
        user.userId.eq(friend.targetId)
          .and(user.userId.ne(userId))
          .and(friend.status.eq(FriendStatus.NOTFRIEND.getStatus()))
      ).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(FriendStatus.FRIEND.getStatus()))
          .and(friend.targetId.ne(userId))
      ).stream().distinct().toList();
  }



  @Override
  public Long updateFriends(FriendDto friendDto) {
    return queryFactory.update(friend)
      .set(friend.status,friendDto.getStatus())
      .where((friend.sourceId.eq(friendDto.getSourceId()).and(friend.targetId.eq(friendDto.getTargetId())))
        .or(friend.sourceId.eq(friendDto.getTargetId()).and(friend.targetId.eq(friendDto.getSourceId()))))
      .execute();
  }

  @Override
  public Long deleteFriends(FriendDto friendDto) {
    return queryFactory.delete(friend)
      .where((friend.sourceId.eq(friendDto.getSourceId()).and(friend.targetId.eq(friendDto.getTargetId())))
        .or(friend.sourceId.eq(friendDto.getTargetId()).and(friend.targetId.eq(friendDto.getSourceId()))))
      .execute();
  }

}

 

좀 간단하게 짜긴했다.

우선 이렇게 API개발을 하고, 플러터에서 하나씩 붙여보면서 수정을 하자

 

BooleanExpression은 한곳에서 검증을 관리해주지만, 사실 그렇게 복잡하지않으면 안쓰는게 좋은 것 같기도하다

왜냐면 메소드 안에 하나의 내용이 최대한 간결하게 담기는게 좋은것 같다고 생각하기때문이다.

반응형