ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [RESTFUL 학습] JPA를 이용한 CRUD 심화(유저 -게시물 연동)
    SPRING/WEBSERVICE 2020. 10. 4. 01:03

    개인 유저별로 작성할 수 있는 게시물에 대한 테이블을 JPA를 이용하여 작성하고 운영하려면, USER (1) ----> POST (N) 매핑이 되어야 된다. 즉 유저 1명 당 게시물이 0개 ~ N개의 글을 올릴 수 있기 때문에 해당하는 소스를 작성해야 된다.

     

    POST 객체

    아래 대부분의 내용은 이전에 생성하였던 JPA Entity 내용과 동일하나, @ManyToOne(fetch = FetchType.LAZY) 어노테이션을 사용한 부분이 다르다. POST는 N에 해당하고 User는 1에 해당하기 때문에 ManyToOne 어노테이션을 사용하였다.

     

    import com.fasterxml.jackson.annotation.JsonIgnore;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import javax.persistence.*;
    
    @Entity
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Post {
    
        @Id
        @GeneratedValue
        private Integer id;
    
        private String description;
    
        // User : Post -> 1: (0~N), Main : Sub -> Parent : Child)
        // FetchType Lazy : 지연로딩 (해당 Entity가 필요할 때, 즉 명시적으로 가져올때에만 연동)
        @ManyToOne(fetch = FetchType.LAZY)
        @JsonIgnore
        private User user;
    
    }
    

    User 객체 

    -> @OneToMany 어노테이션을 이용하여 Post 객체와 매핑한다.

    @Data
    @AllArgsConstructor
    // <!-- 아래와 같이도 표현가능 -->
    //@JsonIgnoreProperties(value={"password"})
    @NoArgsConstructor
    // @JsonFilter("UserInfo")
    @ApiModel(description = "사용자 상세 정보를 위한 도메인 객체")
    @Entity
    public class User {
    
        @Id
        @GeneratedValue
        private Integer id;
        @Size(min=2, message ="Name은 2글자 이상 입력해 주세요.")
        @ApiModelProperty(notes ="사용자의 이름을 입력해주세요.")
        private String name;
        @Past
        @ApiModelProperty(notes ="사용자의 등록일을 입력해주세요.")
        private Date joinDate;
    
        //@JsonIgnore
    
        @ApiModelProperty(notes ="사용자의 패스워드를 입력해주세요.")
        private String password;
        // @JsonIgnore
    
        @ApiModelProperty(notes ="사용자의 주민번호를 입력해주세요.")
        private String ssn;
    
        @OneToMany(mappedBy = "user")
        private List<Post> posts;
    
    
        public User(int id, String name, Date joinDate, String password, String ssn) {
            this.id = id;
            this.name = name;
            this.joinDate = joinDate;
            this.password= password;
            this.ssn = ssn;
         }
    }
    

    PostRepository 

    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface PostRepository extends JpaRepository<Post, Integer> {
        
    }
    

    data.sql

    -> 테스트 데이터 post 테이블에 추가

    insert into post values(10001,'My first post', 90001);
    insert into post values(10002,'My second post', 90001);

     

    UserJpaController

    -> 해당 id의 Post 내역을 구하는 메서드

      // jpa/users/90001/posts
        @GetMapping("/users/{id}/posts")
        public List<Post> retrieveAllPostsByUser(@PathVariable int id) {
            Optional<User> user = userRepository.findById(id);
            if(!user.isPresent()) {
                throw new UserNotFoundException(String.format("ID[%s] not found",id));
            }
    
            return user.get().getPosts();
        }

    -> 해당 id의 Post(게시물)를 추가하는 메서드 (post 방식)

        // 데이터 추가
        @PostMapping("/users/{id}/posts")
        public ResponseEntity<User> createUser(@PathVariable int id, @RequestBody Post post) {
    
            Optional<User> user = userRepository.findById(id);
            if(!user.isPresent()) {
                throw new UserNotFoundException(String.format("ID[%s] not found",id));
            }
            post.setUser(user.get());
            Post savedPost = postRepository.save(post);
    
            URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                    .path("/{id}")
                    .buildAndExpand(savedPost.getId())
                    .toUri();
    
            return ResponseEntity.created(location).build();
        }

     

Designed by Tistory.