본문 바로가기

⭐ SpringBoot/SpringBoot + CRUD

[INSERT] 특정 폼으로 정의된 데이터를 INSERT하는 프로세스

# 전체적인 흐름에 대한 설명은 아래와 같다.
(1. form저장 2. dto를 entity로 변환 3. Repository 저장 4. return 신규 URL)

 Form 데이터의 값 action api 로 넘긴다 api가 받아 dto에 담아둔다 dto에 담긴 데이터를 entity로 변환한다 변환된 데이터는 Repository Interface CrudRepository를 호출 및 저장한다 redirect: 리턴으로 신규로 생성된 id 값으로 리턴을 수행한다.

 

흐름정리
뷰템플릿 Form으로 데이터의 값을 받는다. → 받은값을 action 태그를 통해 api로 넘긴다. → 해당 api는 넘어온 값을 dto에 담아두기 위해 dto를 생성하고 값의 자바 타입들을 정의한 후 변수로 설정한다.
→ 받아온 데이터를 DB에 저장하기위해 entity로 변환한다. (entity에는 컬럼 어노테이션과 자바 타입등이 정의된다.) 

→ 변환된 entity를 Repository 인터페이스로에 extends로 정의된 CrudRepository를 호출하여 저장한다.
→ redirect: 리턴을 통해 해당 URL로 Redirect를 수행한다.

# 특정 폼으로 정의된 데이터를 INSERT하는 프로세스에 대해서 설명한다.

1. 특정 폼이란 아래와 같은 폼 입력 페이지를 나타낸다.

2. 위의 폼 페이지에 데이터가 입력되어 실제 페이지에 추가되는 과정에 대해서 알아본다.

이전에 작성한 내용이지만 다시한번 정리한다.

2022.04.22 - [⭐ SpringBoot/개념] - DTO의 역할 및 form 데이터 처리

 

DTO의 역할 및 form 데이터 처리

# DTO의 역할? DTO는 클라이언트 요청에 포함된 데이터를 담아 서버 측에 전달하고, 서버 측의 응답 데이터를 담아 클라이언트에 전달하는 계층간 전달자 역할을 합니다. HTML 코드의

may9noy.tistory.com

# DTO의 역할?

DTO는 클라이언트 요청에 포함된 데이터를 담아 서버 측에 전달하고, 서버 측의 응답 데이터를 담아 클라이언트에 전달하는 계층간 전달자 역할을 합니다.

예를들어 위의 Form형식의 사이트에 값을 입력하면 dto는 클라이언트가 입력한 값을 서버측으로 전달한다. 반대의 경우도 마찬가지이다. 그래서 Form 형식과 dto의 형식의 맵핑이 중요한 이유이다.

HTML 코드의 action의 의미?

<form> 태그의 action 속성은 폼 데이터(form data)를 서버로 보낼 때 해당 데이터가 도착할 URL을 명시한다.

아래의 코드처럼 form 태그에서 데이터를 받아 폼 데이터를 서버로 보낼때 해당 form 값이 도착할 URL을 명시 한다.

아래의 URL은 /article/create 라는 URL에 해당 form 값을 전달하라는 의미로 볼 수 있다.

form에 입력된 데이터를 /article/create라는 컨트롤러에 전달하는 의미라고 볼 수 있다.

그렇다면 값을 받은 URL인 /article/create 컨트롤러의 코드를 보면 아래와 같다.

new.mustache라는 form데이터를 입력하는 화면에서 클라이언트가 데이터를 입력하면 /article/create라는 컨트롤러로 입력된 값이 전달된다. 전달된 값은 아래와 같이 ArticleForm이라는 클래스로 전달되고 이 클래스를 form이라고 명명한다.

그러니까 외부 클라이언트가 입력한 값을 중간에 어딘가에 담아둬야 하는데 그 역할을 하는게 dto의 역할이다.

그리고 ArticleForm에 담긴 데이터를 DB에 저장하기 위해 Article article = form.toEntity(); → Dto를 Entity로 변환한다.

자 그렇다면 form.toEntity();를 활용하여 Dto를 Entity로 변환하는 이유는 무엇일까? 아래의 접기 내용을 펼쳐서 확인한다.

(접은 내용은 Article 클래스의 내용이다.)

결론은 DB에서 dto에 저장된 값이 어떤 값인지 정의하고 인식하기 위해서 entity에 해당 값들에 대한 컬럼정보를 지정해 놓았다고 할 수 있다.

더보기
@Entity //DB가 해당 객체를 인식 가능
@ToString
@AllArgsConstructor
@Getter
public class Article {

    // 기본적으로 Entity에는 대표값을 넣어줘야 한다.

    @Id // 사람으로 치면 주민등록 번호 같은 대표값 개념이다.
    @GeneratedValue(strategy = GenerationType.IDENTITY) // DB가 id를 자동생성하는 어노테이션!
    private Long id;

    @Column // DB에서 이해할수 있도록 Column 이라는 어노테이션을 붙여준다.
    private String title;

    @Column
    private String content;

그렇다면 DB에 저장되는 로직에 대해서 알아보면 아래와 같다. 위의 Article saved = articleRepository.save(article); 내용과 같이 entity로 변환된 데이터를 받아 articleRepository.save(article)를 통해 데이터를 저장한다.

ArticleRepository articleRepository 의 내용은 아래와 같다. 별다른게 없다. extends의 개념도 아래의 내용에 추가 하였다.

더보기
public interface ArticleRepository extends CrudRepository<Article, Long> {
    //ArticleRepository는 CrudRepository가 가지고 있는 서비스를 정의 없이 바로 사용이 가능하다.
    //CrudRepository는 2개의 값이 필요하다. 관리대상엔티티, 관라대상 엔티티에서 정한 대표 타입을 지정 id 타입이 Long 이었기 때문에 Long을 지정

    @Override
    ArrayList<Article> findAll();
}

아래의 내용을 보면 class Car가 Vehicle을 extends하여 Vehicle 값을 어떤 설정없이 바로 사용할 수 있는 모습을 볼 수 있다. 상속은 두가지가 존재한다. 아래와 같이 extends로 상속하는 개념이 있고 다른 하나는 implements를 통해 상속을 받는 경우이다. 여기서 extends와 implements를 간단하게 설명하면 extends는 재정의가 필요없이 값을 그대로 사용 가능하고 implements는 해당 값을 재정의 후 사용해야 한다고 간단하게 이해하고 넘어간다.

class Vehicle {
  protected int speed = 3;
  
  public int getSpeed(){
    return speed;
  }
  public void setSpeed(int speed){
    this.speed = speed;
  }
}

class Car extends Vehicle{
  public void printspd(){
    System.out.println(speed);
  }
}

public class ExtendsSample {
  public static main (String[] args){
    Car A = new Car();
    System.out.println(A.getSpeed());
    A.printspd();
  }
}

ArticleForm 클래스 파일의 내용을 보면 아래와 같다.

여기서 redirect: 의 의미를 알아보자

아래와 같이 return "redirect:/articles/" + saved.getId(); 로 설정되면, 실제 url은 아래와 같은 형태로 변환다.

return "redirect:/articles/" + saved.getId();

redirect를 수행하는데 해당 경로로 "redirect:/articles/" 위에서 생성된 id주소로 리다이렉트를 요청하는 의미이다.

그렇다면 Entity란 무엇인가?

@Entity : JPA에서 엔티티란 쉽게 생각하면, DB 테이블에 대응하는 하나의 클래스라고 생각할 수 있다.
@Entity가 붙은 클래스는 JPA가 관리해주며, JPA를 사용해서 DB 테이블과 매핑할 클래스는 @Entity를 꼭 붙여야만 매핑이 된다. 

그말인 즉슨, DB로 사용하기 위한 클래스는 @Entity를 붙이고 해당 컬럼 값은 아래와 같이 @Column값을 붙여서 테이블과 컬럼 형태의 구성을 해야한다.