TIL
[TIL] 230529 <Spring> 회원가입, 로그인 기능이 있는 투두앱 백엔드 서버 만들기 (1)
- -
[일정과 댓글의 연관 관계 설정]
- 각 일정에 댓글을 작성할 수 있도록 관련 클래스를 추가하고 연관 관계를 설정합니다.
- 매핑 관계를 설정합니다. (1:1 or N:1 or N:M)
entity>Schedule
@Entity // JPA가 관리할 수 있는 Entity 클래스 지정
@Getter
@Setter
@Table(name = "schedule") // 매핑할 테이블의 이름을 지정
@NoArgsConstructor
public class Schedule extends Timestamped{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "content", nullable = false, length = 500)
private String content;
@Column(name = "manager", nullable = false)
private String manager;
@Column(name = "password", nullable = false)
private String password;
@OneToMany(mappedBy = "schedule")
private List<Comment> commentList = new ArrayList<>();
public Schedule(ScheduleRequestDto requestDto) {
this.title = requestDto.getTitle();
this.content = requestDto.getContent();
this.manager = requestDto.getManager();
this.password = requestDto.getPassword();
}
public void update(ScheduleRequestDto requestDto) {
this.title = requestDto.getTitle();
this.content = requestDto.getContent();
this.manager = requestDto.getManager();
this.password = requestDto.getPassword();
}
}
entity>Comment
@Entity
@Getter
@Setter
@Table(name = "comments")
@NoArgsConstructor
public class Comment extends Timestamped{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "content", nullable = false, length = 500)
private String content;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne
@JoinColumn(name = "schedule_id", nullable = false)
private Schedule schedule;
}
[댓글 등록]
기능
- 선택한 일정이 있다면 댓글을 등록합니다.
조건
- 댓글이 등록되었다면 client에게 반환합니다.
- 선택한 일정이 DB에 저장되어 있어야 합니다.
- 댓글을 식별하는 고유번호, 댓글 내용, 댓글을 작성한 사용자 아이디, 댓글이 작성된 일정 아이디, 작성일자를 저장할 수 있습니다.
⚠️ 예외 처리
- 선택한 일정의 ID를 입력 받지 않은 경우
- 댓글 내용이 비어 있는 경우
- 일정이 DB에 저장되지 않은 경우
controller>CommentController
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class CommentController {
private final CommentService commentService;
// 댓글 작성
@PostMapping("/comment")
public CommentResponseDto createComment(@RequestBody CommentRequestDto requestDto) {
return commentService.createComment(requestDto);
}
}
dto>CommentRequestDto
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CommentRequestDto {
private Long scheduleId;
private String content;
private String userId;
}
dto>CommentResponseDto
@Getter
public class CommentResponseDto {
private Long id;
private String content;
private String userId;
private Long scheduleId;
private LocalDateTime createdAt;
public CommentResponseDto(Comment comment) {
this.id = comment.getId();
this.content = comment.getContent();
this.userId = comment.getUserId();
this.scheduleId = comment.getSchedule().getId();
this.createdAt = comment.getCreatedAt();
}
}
service>CommentService
@Service
@RequiredArgsConstructor
public class CommentService {
private final CommentRepository commentRepository;
private final ScheduleRepository scheduleRepository;
public CommentResponseDto createComment(CommentRequestDto requestDto) {
Long scheduleId = requestDto.getScheduleId();
if (scheduleId == null) {
throw new IllegalArgumentException("댓글을 작성할 일정의 ID가 입력되지 않았습니다.");
}
String content = requestDto.getContent();
if (content.isEmpty()) {
throw new IllegalArgumentException("댓글의 내용이 비어있습니다.");
}
String userId = requestDto.getUserId();
if (userId.isEmpty()) {
throw new IllegalArgumentException("작성자 ID가 입력되지 않았습니다.");
}
// 선택한 일정이 DB에 저장되어 있는지 확인
Optional<Schedule> checkSchedule = scheduleRepository.findById(scheduleId);
if (checkSchedule.isEmpty()) {
throw new NoSuchElementException("선택한 일정을 찾을 수 없습니다.");
}
Schedule schedule = checkSchedule.get();
Comment comment = new Comment(content, userId, schedule);
commentRepository.save(comment);
return new CommentResponseDto(comment);
}
}
entity>Comment
@Entity
@Getter
@Setter
@Table(name = "comments")
@NoArgsConstructor
public class Comment extends Timestamped{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "content", nullable = false, length = 500)
private String content;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne
@JoinColumn(name = "schedule_id", nullable = false)
private Schedule schedule;
public Comment(String content, User user, Schedule schedule) {
this.content = content;
this.user = user;
this.schedule = schedule;
}
}
repository>CommentRepository
public interface CommentRepository extends JpaRepository<Comment,Long> {
}
[댓글 수정]
기능
- 선택한 일정의 댓글을 수정합니다.
조건
- 댓글이 수정되었다면 수정된 댓글을 반환합니다.
- 댓글 내용만 수정 가능합니다.
- 선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.
⚠️ 예외 처리
- 선택한 일정이나 댓글의 ID를 입력 받지 않은 경우
- 일정이나 댓글이 DB에 저장되지 않은 경우
- 선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우
controller>CommentController
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class CommentController {
private final CommentService commentService;
// 댓글 수정
@PutMapping("/comment/{commentId}")
public CommentResponseDto updateComment(@PathVariable Long commentId, @RequestBody CommentRequestDto requestDto) {
return commentService.updateComment(commentId, requestDto);
}
}
service>CommentService
@Service
@RequiredArgsConstructor
public class CommentService {
private final CommentRepository commentRepository;
private final ScheduleRepository scheduleRepository;
@Transactional
public CommentResponseDto updateComment(Long commentId, CommentRequestDto requestDto) {
Long scheduleId = requestDto.getScheduleId();
if (scheduleId == null) {
throw new IllegalArgumentException("댓글을 작성할 일정의 ID가 입력되지 않았습니다.");
}
if (commentId == null) {
throw new IllegalArgumentException("댓글의 ID가 입력되지 않았습니다.");
}
String newContent = requestDto.getContent();
if (newContent.isEmpty()) {
throw new IllegalArgumentException("댓글의 내용이 비어있습니다.");
}
String userId = requestDto.getUserId();
if (userId.isEmpty()) {
throw new IllegalArgumentException("작성자 ID가 입력되지 않았습니다.");
}
// 선택한 일정이 DB에 저장되어 있는지 확인
Optional<Schedule> checkSchedule = scheduleRepository.findById(scheduleId);
if (checkSchedule.isEmpty()) {
throw new NoSuchElementException("선택한 일정을 찾을 수 없습니다.");
}
// 선택한 댓글이 DB에 저장되어 있는지 확인
Optional<Comment> checkComment = commentRepository.findById(commentId);
if (checkComment.isEmpty()) {
throw new NoSuchElementException("선택한 댓글을 찾을 수 없습니다.");
}
Comment comment = checkComment.get();
if (!comment.getUserId().equals(userId)) {
throw new IllegalArgumentException("선택한 댓글의 사용자가 현재 사용자와 일치하지 않습니다.");
}
// 댓글 내용이 변경되었는지 확인하고 변경된 경우에만 업데이트
if (!newContent.equals(comment.getContent())) {
comment.setContent(newContent);
commentRepository.save(comment);
}
return new CommentResponseDto(comment);
}
}
[댓글 삭제]
기능
- 선택한 일정의 댓글을 삭제합니다.
조건
- 성공했다는 메시지와 상태 코드 반환하기
- 선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.
⚠️ 예외 처리
- 선택한 일정이나 댓글의 ID를 입력받지 않은 경우
- 일정이나 댓글이 DB에 저장되지 않은 경우
- 선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우
controller>CommentController
@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class CommentController {
private final CommentService commentService;
// 댓글 삭제
@DeleteMapping("/comment/{commentId}")
public ResponseEntity<Response> deleteComment(@PathVariable Long commentId, @RequestBody CommentRequestDto requestDto) {
return commentService.deleteComment(commentId, requestDto);
}
}
service>CommentService
@Service
@RequiredArgsConstructor
public class CommentService {
private final CommentRepository commentRepository;
private final ScheduleRepository scheduleRepository;
public ResponseEntity<Response> deleteComment(Long commentId, CommentRequestDto requestDto) {
Long scheduleId = requestDto.getScheduleId();
if (scheduleId == null) {
throw new IllegalArgumentException("댓글을 작성할 일정의 ID가 입력되지 않았습니다.");
}
if (commentId == null) {
throw new IllegalArgumentException("댓글의 ID가 입력되지 않았습니다.");
}
String userId = requestDto.getUserId();
if (userId.isEmpty()) {
throw new IllegalArgumentException("작성자 ID가 입력되지 않았습니다.");
}
// 선택한 일정이 DB에 저장되어 있는지 확인
Optional<Schedule> checkSchedule = scheduleRepository.findById(scheduleId);
if (checkSchedule.isEmpty()) {
throw new NoSuchElementException("선택한 일정을 찾을 수 없습니다.");
}
// 선택한 댓글이 DB에 저장되어 있는지 확인
Optional<Comment> commentOptional = commentRepository.findById(commentId);
if (commentOptional.isEmpty()) {
throw new NoSuchElementException("선택한 댓글을 찾을 수 없습니다.");
}
Comment comment = commentOptional.get();
// 선택한 댓글의 사용자가 현재 사용자와 일치하지 않으면 예외 발생
if (!comment.getUserId().equals(userId)) {
throw new IllegalArgumentException("선택한 댓글의 사용자가 현재 사용자와 일치하지 않습니다.");
}
// 댓글 삭제
commentRepository.delete(comment);
Response response = new Response(HttpStatus.OK.value(), "댓글이 성공적으로 삭제되었습니다.");
// 성공 메시지와 상태 코드 반환
return ResponseEntity.ok(response);
}
}
'TIL' 카테고리의 다른 글
[TIL] 230531 <Spring> Filter (0) | 2024.05.31 |
---|---|
[TIL] 230530 <Spring> 회원가입, 로그인 기능이 있는 투두앱 백엔드 서버 만들기 (2) (0) | 2024.05.30 |
[TIL] 230528 <Spring> My Select Shop (0) | 2024.05.28 |
[TIL] 230527 <Spring> 사용자 관리하기, 데이터 검증하기 (0) | 2024.05.27 |
[TIL] 230524 <Spring> 인증과 인가, 사용자 관리하기 (0) | 2024.05.24 |
Contents
소중한 공감 감사합니다