반응형
Follow.java
- Follow라는 모델을 만든다.
- @JoinColumn 어노테이션으로 DB의 컬럼명을 커스텀한다.
- @Table 컬럼을 통해 한 테이블에 동일한 관계 정보가 중복되지 않게 들어가도록 Uniqe 제약조건을 설정한다.
(한 컬럼만 걸거면 그냥 @Column(unique = true)하면 되긴하다.)
- User 테이블이 1이고 Follow 테이블이 N 이니까 @ManytoOne 어노테이션을 적는다
- 데이터 생성 정보 컬럼도 넣어준다.
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@Table(
uniqueConstraints = {
@UniqueConstraint(
name = "follow_uk",
columnNames = {"fromUserId", "toUserId"} //실제 db이 컬럼명이 들어가야한다.
)
}
)
public class Follow {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@JoinColumn(name = "fromUserId") // DB컬럼명 설정
@ManyToOne
private User fromUser; //팔로우 하는애
@JoinColumn(name = "toUserId")
@ManyToOne
private User toUser; //팔로우 받는애
private LocalDateTime createDate;
@PrePersist
public void createDate(){
this.createDate = LocalDateTime.now();
}
}
FollowApiController
- 팔로우 메소드, 언팔로우 메소드를 만든다.
- 팔로우(언팔라우) 주체를 알아야 하기 때문에 @AuthenticationPrincipal PrincipalDetails principalDetails 를 매개변수로 넣어준다.
- 또한 팔로우,언팔 대상(toUserId)를 매개변수로 넣어준다.
@RequiredArgsConstructor
@RestController
public class FollowApiController {
private final FollowService followService;
@PostMapping("/api/follow/{toUserId}")
public ResponseEntity<?> follow(@AuthenticationPrincipal PrincipalDetails principalDetails,
@PathVariable int toUserId){
followService.follow(principalDetails.getUser().getId(), toUserId);
return new ResponseEntity<>(new CMRespDto<>(1, "팔로우성공", null), HttpStatus.OK);
}
@DeleteMapping("/api/follow/{toUserId}")
public ResponseEntity<?> unfollow(@AuthenticationPrincipal PrincipalDetails principalDetails,
@PathVariable int toUserId){
followService.unfollow(principalDetails.getUser().getId(), toUserId);
return new ResponseEntity<>(new CMRespDto<>(1, "언팔로우 성공", null), HttpStatus.OK);
}
}
FollowService
-실제 팔로우, 언팔로우 로직이 실행되는곳
- DB에 영향을 주는 메소드기 때문에 @Transactional 어노테이션 넣어준다.
@RequiredArgsConstructor
@Service
public class FollowService {
private final FollowRepositoy followRepositoy;
@Transactional
public void follow(int fromUserId, int toUserId){
try {
followRepositoy.mFollow(fromUserId,toUserId);
} catch (Exception e){
throw new CustomApiException("이미 팔로우 했습니다.");
}
}
@Transactional
public void unfollow(int fromUserId, int toUserId){
followRepositoy.mUnFollow(fromUserId,toUserId);
}
}
CustomApiException
public class CustomApiException extends RuntimeException{
private static final long serialVersionUID = 1L;
public CustomApiException(String message){
super(message);
}
}
ControllerExceptionHandler
- apiException 메소드를 만든다. 여기에선 CMRespDto 매개변수에 에러메시지만 받고, errorMap은 null로만 받는다.
@RestController
@ControllerAdvice //모든 Exception들을 낚아챔
public class ControllerExceptionHandler {
...
@ExceptionHandler(CustomApiException.class)
public ResponseEntity<?> apiException(CustomApiException e){
return new ResponseEntity<>(new CMRespDto<>(-1, e.getMessage(), null), HttpStatus.BAD_REQUEST);
}
}
FollowRepositoy
- 네이티브 쿼리로 작성
- ':' 은 매개변수에 들어온 값을 바인딩하겠다는 의미다.
public interface FollowRepositoy extends JpaRepository<Follow,Integer>{
@Modifying //INSERT, DELETE, UPDATE를 네이티브쿼리로 작성하려면 해당 어노테이션 필요
@Query(value = "INSERT INTO follow(fromUserId, toUserId, createDate) Values(:fromUserId, :toUserId, now())", nativeQuery = true)
void mFollow(int fromUserId, int toUserId);
@Modifying
@Query(value = "DELETE FROM follow WHERE fromUserId = :fromUserId AND toUserId = :toUserId", nativeQuery = true)
void mUnFollow(int fromUserId, int toUserId);
}
'Study > SpringBoot' 카테고리의 다른 글
[Springboot] 이미지 업로드 - 2 유효성 검사 및 양방향 매칭 설정 (0) | 2022.05.22 |
---|---|
[Springboot] 이미지 업로드 - 1 이미지 저장(로컬 및 DB) (0) | 2022.05.21 |
[Springboot] 회원정보 수정1 - 로그인한 유저 정보 보이기 (0) | 2022.05.18 |
[Springboot] 회원가입 구현 (0) | 2022.05.16 |
[SpringBoot] 사용자- 게시글 one-to-many, many-to-one 관계설정 (0) | 2022.05.12 |