전체 스택 Reddit 클론 - Spring Boot, React, Electron 앱 - 2부

전체 스택 Reddit 클론 - Spring Boot, React, Electron 앱 - 2부



소개



Spring Boot 및 React를 사용하여 Reddit 클론 생성의 2부에 오신 것을 환영합니다.

프로젝트를 초기화하고 필요한 모든 종속성을 추가했습니다. 이 문서에서는 백엔드를 완성하는 데 필요한 모든 엔터티 및 리포지토리 생성에 대해 다룰 것입니다!

중요한 링크


  • 백엔드 소스: https://github.com/MaxiCB/vox-nobis/tree/master/backend
  • 프런트엔드 소스: https://github.com/MaxiCB/vox-nobis/tree/master/client
  • 실시간 URL: 진행 중

  • 1부: 도메인 엔터티 생성 📝



    응용 프로그램이 갖게 될 다양한 도메인 엔터티를 모두 다루겠습니다. com.your-name.backend 안에 모델이라는 새 패키지를 만들고 다음 클래스를 추가합니다.

    참고: 1부에서 Lombok을 종속 항목으로 설치했습니다. 개발 프로세스 전반에 걸쳐 다양한 Lombok 주석을 사용할 것입니다. 이러한 주석에 액세스하려면 IDE에서 주석 처리를 활성화해야 합니다. 이에 대한 추가 지침은 여기에서 Lombok 설정 가이드를 볼 수 있습니다. - https://www.baeldung.com/lombok-ide

    참고: 경우에 따라 필드 유효성 검사를 위해 pom.xml 파일에 다음 종속성을 추가해야 할 수도 있습니다.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    


  • 사용자: 고유한 userId, 사용자 이름, 암호, emailAddress, creationDate, accountStatus가 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        import javax.persistence.*;
        import javax.validation.constraints.Email;
        import javax.validation.constraints.NotBlank;
        import java.time.Instant;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Table(name = "users")
        @Entity
        public class User {
            @Id
            @SequenceGenerator(name = "USER_GEN", sequenceName = "SEQ_USER", allocationSize = 1)
            @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_GEN")
            private Long userId;
            @NotBlank(message = "Username is required")
            private String username;
            @NotBlank(message = "Password is required")
            private String password;
            @Email
            @NotBlank(message = "Email is required")
            private String email;
            private Instant creationDate;
            private boolean accountStatus;
        }
    
    


  • 게시물: 고유한 postId, postName, url, description, voteCount, user, creationDate, subreddit이 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Builder;
        import lombok.Data;
        import lombok.NoArgsConstructor;
        import org.springframework.lang.Nullable;
    
        import javax.persistence.*;
        import javax.validation.constraints.NotBlank;
        import java.time.Instant;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        @Entity
        public class Post {
            @Id
            @SequenceGenerator(name = "POST_GEN", sequenceName = "SEQ_POST", allocationSize = 1)
            @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "POST_GEN")
            private Long postId;
            @NotBlank(message = "Post Title is required")
            private String postTitle;
            @Nullable
            private String url;
            @Nullable
            @Lob
            private String description;
            private Integer voteCount;
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "userId", referencedColumnName = "userId")
            private User user;
            private Instant creationDate;
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "id", referencedColumnName = "id")
            private Subreddit subreddit;
        }
    
    


  • Subreddit: 고유 ID, 이름, 설명, 게시물, 생성 날짜, 사용자가 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Builder;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        import javax.persistence.*;
        import javax.validation.constraints.NotBlank;
        import java.time.Instant;
        import java.util.List;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        @Entity
        public class Subreddit {
            @Id
            @SequenceGenerator(name = "SUB_GEN", sequenceName = "SEQ_SUB", allocationSize = 1)
            @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SUB_GEN")
            private Long id;
            @NotBlank(message = "Subreddit name is required")
            private String name;
            @NotBlank(message = "Subreddit description is required")
            private String description;
            @OneToMany(fetch = FetchType.LAZY)
            private List<Post> posts;
            private Instant creationDate;
            @ManyToOne(fetch = FetchType.LAZY)
            private User user;
        }
    
    


  • 투표: 고유 ID, 게시물, 사용자가 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Builder;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        import javax.persistence.*;
        import javax.validation.constraints.NotNull;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        @Entity
        public class Vote {
            @Id
            @GeneratedValue(strategy = GenerationType.SEQUENCE)
            private Long voteId;
            private VoteType voteType;
            @NotNull
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "postId", referencedColumnName = "postId")
            private Post post;
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "userId", referencedColumnName = "userId")
            private User user;
        }
    
    


  • 설명: 고유한 id, text, post, creationDate, user가 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Builder;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        import javax.persistence.*;
        import javax.validation.constraints.NotEmpty;
        import java.time.Instant;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        @Entity
        public class Comment {
            @Id
            @GeneratedValue(strategy = GenerationType.SEQUENCE)
            private Long id;
            @NotEmpty
            private String text;
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "postId", referencedColumnName = "postId")
            private Post post;
            private Instant creationDate;
            @ManyToOne(fetch = FetchType.LAZY)
            @JoinColumn(name = "userId", referencedColumnName = "userId")
            private User user;
        }
    
    


  • VoteType ENUM: 찬성, 반대

  •     public enum VoteType {
            UPVOTE(1), DOWNVOTE(-1);
    
            VoteType(int direction) {}
        }
    
    


  • AccountVerificationToken: 고유한 ID, 토큰, 사용자, 만료 날짜가 있습니다.

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Builder;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        import javax.persistence.*;
        import java.time.Instant;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        @Builder
        @Table(name = "token")
        @Entity
        public class AccountVerificationToken {
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private Long id;
            private String token;
            @OneToOne(fetch = FetchType.LAZY)
            private User user;
            private Instant expirationDate;
        }
    
    


  • NotificationEmail: 제목, 수신자, 본문

  •   package com.maxicb.backend.model;
    
        import lombok.AllArgsConstructor;
        import lombok.Data;
        import lombok.NoArgsConstructor;
    
        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class NotificationEmail {
            private String subject;
            private String recepient;
            private String body;
        }
    
    


    2부: 리포지토리 생성 👩‍



    이제 데이터베이스에 엔터티를 저장할 책임이 있는 리포지토리를 다루어야 합니다. com.you-name.backend 안에 저장소라는 새 패키지를 만들고 다음 인터페이스를 추가합니다.
  • 사용자 저장소:

  •     package com.maxicb.backend.repository;
    
        import com.maxicb.backend.model.User;
        import org.springframework.data.repository.CrudRepository;
    
        import java.util.Optional;
    
        public interface UserRepository extends CrudRepository<User, Long> {
            Optional<User> findByUsername(String username);
        }
    


  • 포스트 저장소:

  •     package com.maxicb.backend.repository;
    
        import com.maxicb.backend.model.Post;
        import com.maxicb.backend.model.Subreddit;
        import com.maxicb.backend.model.User;
        import org.springframework.data.repository.CrudRepository;
    
        import java.util.List;
    
        public interface PostRepository extends CrudRepository<Post, Long> {
            List<Post> findAllBySubreddit(Subreddit subreddit);
    
            List<Post> findByUser(User user);
        }
    


  • 서브레딧 저장소:

  •   package com.maxicb.backend.repository;
    
      import com.maxicb.backend.model.Subreddit;
      import org.springframework.data.repository.CrudRepository;
    
      import java.util.Optional;
    
      public interface SubredditRepository extends CrudRepository<Subreddit, Long> {
          Optional<Subreddit> findByName(String subredditName);
      }
    


  • 투표 저장소:

  •     package com.maxicb.backend.repository;
    
        import com.maxicb.backend.model.Post;
        import com.maxicb.backend.model.User;
        import com.maxicb.backend.model.Vote;
        import org.springframework.data.repository.CrudRepository;
    
        import java.util.Optional;
    
        public interface VoteRepository extends CrudRepository<Vote, Long> {
            Optional<Vote> findTopByPostAndUserOrderByVoteIdDesc(Post post, User currentUser);
        }
    


  • 댓글 저장소:

  •     package com.maxicb.backend.repository;
    
        import com.maxicb.backend.model.Comment;
        import com.maxicb.backend.model.Post;
        import com.maxicb.backend.model.User;
        import org.springframework.data.repository.CrudRepository;
    
        import java.util.List;
    
        public interface CommentRepository extends CrudRepository<Comment, Long> {
            List<Comment> findByPost(Post post);
    
            List<Comment> findAllByUser(User user);
        }
    


  • 토큰 저장소:

  •   package com.maxicb.backend.repository;
    
    import com.maxicb.backend.model.AccountVerificationToken;
    import org.springframework.data.repository.CrudRepository;
    
    import java.util.Optional;
    
    public interface TokenRepository extends CrudRepository<AccountVerificationToken, Long> {
        Optional<AccountVerificationToken> findByToken(String token);
    }
    


    결론 🔍


  • 모든 것이 올바르게 구성되었는지 확인하려면 응용 프로그램을 실행하고 콘솔에 오류가 없는지 확인할 수 있습니다. 콘솔 하단을 향해 아래와 유사한 출력이 표시되어야 합니다
  • .


  • 이 기사에서는 Spring Boot 백엔드에 필요한 엔티티와 리포지토리를 생성했습니다. 뒤따를 모든 논리의 토대를 마련합니다.

  • 다음



    등록, 이메일 전송 및 계정 활성화/확인을 구현합니다.

    좋은 웹페이지 즐겨찾기