본문 바로가기
스프링

스프링부트 JPA 게시판 글쓰기 구현

by DarrenH 2022. 1. 7.
반응형

안녕하세요 오늘은 Spring Boot로 게시판으로 만드는 방법을 포스팅하려고 합니다. JPA를 이용하여 게시판을 만들어보겠습니다. 바로 본문으로 들어가겠습니다!

 

먼저 Posts라는 클래스를 생성해줍니다. 이클래스는 DB에 직접 값을 넣는 클래스라 생각하시면 되겠습니다. 이러한 클래스를 Entity클래스 라고 하는데요 이 클래스는 테이블과 링크될 클래스라고 생각하시면 됩니다. 

 

@Getter
@NoArgsConstructor
@Entity   //Table과 link될 클래스임을 명시  Setter 생성 금지 다른 이름으로 정확히 명시해서 set은 가능
public class Posts {

    @Id   //PK 명시
    @GeneratedValue(strategy = GenerationType.IDENTITY)  //auto_increment 명시)
    private Long id;

    @Column(length = 500, nullable = false) //컬럼의 길이 500으로 변경 //null여부
    private String title;

    @Column(columnDefinition = "TEXT", nullable = false) //컬럼속성 변경
    private String content;

    private String author;

    @Builder
    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

}

테스트할때 보니깐columnDefinition은 컬럼속성을 정하는건데요 이걸 안써주면 기본으로 varchar(255)가 들어가더라고요. 

 

PostsRepository 클래스를 만들어야하는데요 이는 JPA의 CRUD기능을 쓰기 위해 만드는 클래스입니다. 

public interface PostsRepository extends JpaRepository<Posts, Long> { }

여기 보시면 interface로 생성된 것을 볼 수 있습니다. 인터페이스를 생성 후 JpaRepository<Entity 클래스, PK 타입> 을 상속 받게 되면 CRUD메소드가 생성됩니다.

 

❗여기서 중요한 점은 Repository클래스(PostsRepository)와 Entity클래스(Posts)가 같은 패키지에 위치해야합니다❗

 

그다음 등록을 하기위해 Controller 클래스를 생성 해보겠습니다. 

 

@RequiredArgsConstructor
@RestController
public class PostApiController {

    private final PostsService postsService;

    @PostMapping("/api/v1/posts")
    public Long save(@RequestBody PostsSaveRequestDto requestDto) {
        return postsService.save(requestDto);
    }
}

이름은 PostsApiController로 만들었으며, 각 어노테이션에 대해 설명드리겠습니다.

어노테이션 설명
@RequiredArgsConstructor final이 붙은 필드를 인자로 하는 생성자를 자동으로 생성해줍니다.
@RestController json형태로 객체를 반환합니다. 
@PostsMapping("/api/v1/posts") 해당 경로를 post방식으로 값을 넘긴다.

 

Service 클래스

@RequiredArgsConstructor
@Service
public class PostsService {
    private final PostsRepository postsRepository;

    @Transactional
    public Long save(PostsSaveRequestDto requestDto) {
        return postsRepository.save(requestDto.toEntity()).getId();
    }

}

위와 같은 @RequiredArgsConstructor어노테이션을 이용하였고 Service 클래스임을 명시해줬습니다. 먼저 위에 Controller 클래스에서도 save메소드가 있었는데 여기 Service클래스에서도 같은 save가 있음을 알 수 있습니다. 이는 보시면 Controller에서 Dto를 받은 후 Service클래스에 위임을 해준 것 인데요. 그리고 Service클래스를 보면 Dto를 받은 후 아까 만들었던 Repository클래스의 save메소드에 넣은후 ID를 return했습니다. 결국엔 이 뜻은 기존 자바에서 JDBC에서 값을 받을때 Connection과 Statement 를 이용하여 값을 받은 것을 @Transactional을 써줌으로써, JDBC 의 트랜잭션을 생략 한 것입니다. 

 

그럼 앞서 DTO클래스도 살펴 보겠습니다.

@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
    private String title;
    private String content;
    private String author;

    @Builder
    public PostsSaveRequestDto(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    public Posts toEntity() {
        return Posts.builder()
                .title(title)
                .content(content)
                .author(author)
                .build();
    }

}

네 보시면 위에 Entity클래스(Posts)는 DB와 직접적으로 링크되어있는 클래스이면 이 DTO클래스는 자바 단에서 값을 저장 하는 곳이라고 생각하시면 되겠습니다. 여기서 보시면 toEntity()메소드를 보시면 Posts클래스에 builder() 메소드를 호출하는데 DTO에 저장된 값을 Entity클래스에 값을 넣는 과정인데요 그냥 넣어도 저희가 알던 인자를 이용하여 값을 전달 할 수도 있는데 이렇게 빌더로 넣는 이유가 있습니다.

 

저희가 sum(int a, int b)라고 생각하면 a 와 b를 바꿔 넣어도 결과값이 b+a가 잘나옵니다. 근데 순서대로 넣지않았을경우 값이 이상해질 수 있으므로 정확히 명시하도록 하기위해 적어준거라도 이해하시면 될거같아요.

 

 

테스트시 정상적으로 insert하는 것을 볼 수 있습니다!

 

반응형