프로젝트 (Java)/예약마켓

[프로젝트] 15. 게시물 관련 DTO 설계 및 게시물 추가 API 구현

hihyuk 2024. 1. 26. 09:51

Comment, Like, Post 엔티티 구현

Comment, Like, Post 엔티티는 게시물과 관련된 데이터 모델을 정의합니다. 각각의 엔티티는 데이터베이스 테이블에 해당하며, JPA를 통해 관리됩니다.

Comment: 게시물에 달린 댓글을 나타냅니다.

@Getter
@Entity
@Table(name = "comments")
@NoArgsConstructor
public class Comment extends BaseTimeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;

    @ManyToOne(fetch= FetchType.LAZY, optional = false)
    @JoinColumn(name = "post_id")
    private Post post;

    @OneToOne(fetch= FetchType.EAGER, optional = false)
    @JoinColumn(name = "writer_id")
    private User writer;

    @Column(name = "content")
    private String content;

    @Builder
    public Comment(Long id, Post post, User writer, String content) {
        this.id = id;
        this.post = post;
        this.writer = writer;
        this.content = content;
    }
}

Like: 게시물에 대한 좋아요를 나타냅니다.

@Getter
@Entity
@Table(name = "likes")
@NoArgsConstructor
public class Like {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "post_id")
    private Post post;

    @JoinColumn(name = "user_id")
    private Long userId;
}

Post: 게시물 자체를 나타냅니다.

@Getter
@Entity
@Table(name = "posts")
@NoArgsConstructor
public class Post extends BaseTimeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;

    @OneToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "user_id")
    private User user;

    @Column(name = "content")
    private String content;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Like> likes = new ArrayList<>();

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Comment> comments = new ArrayList<>();

    @Builder
    public Post(Long id, User user, String content, List<Like> likes, List<Comment> comments) {
        this.id = id;
        this.user = user;
        this.content = content;
        this.likes = likes;
        this.comments = comments;
    }
}

 

PostController 추가

PostController는 게시물 생성 요청을 처리합니다. 사용자 인증 정보를 토큰에서 추출하여 게시물 작성자를 식별합니다.

    @PostMapping
    public void createPost(@RequestBody CreatePostDto postDto) {
        TokenContext context = TokenContextHolder.getContext();
        Long userId = context.getUserId();
        postService.createPost(userId, postDto);
    }

 

CreatePostDto 구현

@Getter
public class CreatePostDto {
    private String content;

    public Post toEntity(Long userId) {
        return Post.builder()
                .user(User.builder().id(userId).build())
                .content(content)
                .likes(new ArrayList<>())
                .comments(new ArrayList<>())
                .build();
    }
}

 

PostRepository 인터페이스

PostRepositoryPost 엔티티에 대한 CRUD 연산을 수행하는 Spring Data JPA 리포지토리입니다.

public interface PostRepository extends JpaRepository<Post, Long> {
}

 

PostService 구현

PostService에서는 실제로 게시물을 데이터베이스에 저장하는 로직을 구현합니다. 사용자 ID와 CreatePostDto를 받아 새로운 게시물을 생성합니다.

@Service
@RequiredArgsConstructor
public class PostService {
    private final PostRepository postRepository;
    private final UserRepository userRepository;

    @Transactional
    public void createPost(Long userId, CreatePostDto postDto) {
        User user = userRepository.findById(userId)
            .orElseThrow(() -> new BadRequestException("사용자를 찾을 수 없습니다."));
        postRepository.save(postDto.toEntity(user));
    }
}

 

결론

이러한 구현을 통해, 사용자는 자신의 생각이나 정보를 다른 사람들과 공유할 수 있는 게시물을 생성할 수 있게 됩니다. 게시물 추가 기능은 사용자 간의 상호작용 및 커뮤니티 형성에 중요한 역할을 합니다.