폼 데이터 (Form Data) : HTML 요소인 <form> 태그에 실려서 전송되는 데이터
인터넷 게시판에 글을 쓸 때 -내용 입력 후 전송을 누르면 게시글이 게시판에 올라간다.
<form> 태그는 웹 브라우저에서 서버로 데이터 전송할 때 사용
<form> 태그는 택배
택배 송장에 수령자, 배송 형태 등을 적듯이
<form> 태그도 데이터 전송 때 어디로 (Where) 어떻게 (How) 적어서 보냄
<form> 태그에 실어서 보낸 데이터는 서버의 컨트롤러가 객체에 담아서 받는다.
이 객체를 DTO 라고 한다. (Data Transfer Object)- DTO 로 받은 데이터는 최종적으로 데이터베이스(DB)에 저장된다.
입력 form -> 서버 (컨트롤러 -> DB)
Form Data를 DTO로 받기
1. 입력 폼 만들기
일단 입력을 받아야 한다. 뷰 페이지에 입력을 받을 수 있는 공간을 만든다 mustache
template에 articles라는 디렉토리 생성
그 안에 new.mustache 파일 - 간단한 입력 받는 뷰페이지
게시판의 제목 입력하는 <input>
내용 입력 <textarea> 태그
전송 버튼 <button> 태그 추가
버튼 속성 = type = submit
mustache 파일을 만들었으면 입력을 처리하는 컨트롤러도 필요
ArticleController.java
기존 처럼 GetMapping과 메서드로 return articles/new 해준다.
이대로는 submit 버튼을 눌러도 아무일도 일어나지 않는다.
<form> data를 where how 처리할지 정해준게 없기 때문
<form> 태그에 정보를 추가해야 한다.
어디로 보내야 하는가 = action 속성
어떻게 보내야 하는가 = method 속성
action : url 연결 주소를 적어 action="/articles/create"로 설정한다.
localhost:8080/articles/create 페이지로 폼데이터를 보내겠다.
method : 속성값 - get/post 2가지 설정할 수 있음
container 로 지정한 form 뒤에 그대로 쓴다.
--------------------------------------------------------------------------------------
이제 <form> 데이터는 articles/create로 보내진다.
여기서 뭔가를 해야한다.
createArticle() 메서드를 선언하고, @PostMapping()으로 받는다.
뷰 페이지에서 <form> 데 이터를 post 방식으로 전송했으니까 받을 때도 postmapping으로 받는다.
# DTO 만들기
<form> 데이터는 사용자가 웹 페이지상에 입력을 했고,
컨트롤러에서는 form 데이터를 받을 때 DTO 형태로 받는다고 했다.
DTO를 받는 형식을 지정할 수 있는 새로운 클래스를 만든다.
firstproject > dto 패키지
그 안에 ArticleForm.java 파일 생성 = form 데이터를 받아올 그릇, DTO 가 된다.
위에서 만든 articles/new에서는 제목과 내용 2가지 데이터를 전송할 것
따라서 DTO에도 필드가 2개가 필요하다.
title 과 content로 설정
private String title, content;
생성자를 추가한다.
이제 articles/new 에서 받은 <form> 데이터는 articles/create로 옮겨지고 컨트롤러의 createArticle Method에 의해
ArticleForm으로 들어가야 한다.
#참고 system.out.println 단축키는 sout + tab키 이다
아까 ArticleForm 에 title과 content 필드를 만들어 놨다.
입력 폼과 DTO를 연결 시켜야 한다.
new.mustache에 name = "title"과 name = "content" 를 추가해준다.
DTO의 필드명과 동일한 이름을 name의 속성값으로 써주면 입력폼에서 작성한 두 데이터가 DTO 해당 필드와 연결된다.
요약
뷰페이지에서 : 입력 받는 공간(제목, 내용) 칸 + action 속성과 method 속성으로 어디로 보낼지, 어떻게 보낼지를 정했다. (new.mustache)
컨트롤러에서 : postmapping으로 받은 데이터를 dto 형태로 만든다.
아직 저장은 안함
DTO 를 데이터베이스에 저장하기
이제 입력 받은걸 DTO 형태로 가공까지 했다.
이제 DTO를 저장해야 한다.
데이터베이스는 데이터를 관리하는 창고이다.
맨첨음 스프링 부트 프로젝트 생성할 때 H2 database를 추가했다.
DB에 java로 명령을 내리는 건 JPA를 통한다.
JPA Java Persistence API : 자바 언어로 DB에 명령을 내리는 도구, 데이터를 객체 지향적으로 관리할 수 있게 해준다.
JPA도 생성할 때 추가 했다.
클라이언트가 서버에 데이터를 입력하면 서버는 JPA를 통해 데이터베이스에 이 데이터를 저장하는 형태이다.
JPA 핵심 도구 : 엔티티와 리파지토리 (entity & repository)
엔티티 : 자바 객체를 데이터베이스가 이해할 수 있게 만든 것 : 이를 기반으로 테이블이 만들어진다.
리파지토리 : 엔티티가 DB 속 테이블에 저장 및 관리될 수 있게 하는 인터페이스
1. DTO를 엔티티로 변환하고
2. 리파지토리를 이용해서 엔티티를 DB에 저장한다
1. DTO를 엔티티로 변환하기
지금은 컨트롤러에서 <form> 데이터를 받아서 DTO 로 변경후 출력만 하고 있다.
이제 이 DTO를 엔티티로 변환하고 리파지토리를 이용해서 엔티티를 DB에 저장할 것이다.
DTO 를 엔티티로 변환하는 방법 : form 객체의 toEntity() 메서드 호출하면 끝이다.
엔티티로 지정할 객체 클래스가 필요하다. - Article class
com.example.firstproject > entity 패키지에 생성한다.
Article이라는 클래스는 DTO 를 엔티티로 변환한 결과가 담긴다. (엔티티이다)
이 클래스가 엔티티임을 선언하는 @Entity 붙인다.
JPA에서 제공하는 어노테이션이고, 이 어노테이션이 붙은 클래스 기반으로 DB에 테이블이 생성된다.
DTO를 선언할 때 처럼 title, content 필드를 선언한다. DB에서 이 필드는 column이 될것이다. @Column를 붙인다.
마지막으로 엔티티의 대푯값을 넣는다. 대푯값은 id 로 선언하고 @id 를 붙인다.
대푯값은 주민번호처럼 이 데이터를 대표할 수 있는 값이다.
@GeneratedValue 를 붙여 대푯값을 자동으로 생성할 수 있도록 한다.
Article 엔티티 중에 제목과 내용이 같은 것이 있어도 대푯값 id로 다른 글임을 구별할 수 있도록 한다.
엔티티는 id title content 컬럼을 가진 테이별 형태 클래스이다.
Artilcle 객체의 생성 및 초기화를 위해 생성자 추가
toEntity() 메서드는 DTO인 form 객체를 엔티티 객체로 변환하는 역할을 해야한다.
ArticleForm class에 toEntity() 메서드가 추가된다.
DTO 객체를 엔티티로 반환해야 한다.
toEntity()는 return new Article() 해야 한다.
파라미터에는 id, title, content가 있고, 아직 Article Form에 id가 없으므로 null, title, content로 일단 만들어 둔다.
2. 리파지토리로 엔티티를 DB에 저장하기
ArticleController에 리파지토리가 있다는 가정하에 코드 작성
articleRepository.save() 메서드를 호출해서 article 엔티티를 저장한다.
save() 메서드는 저장된 엔티티를 반환하기 때문에 Article 타입의 saved 에 받아온다
--- 리파지토리 만들기
ArticleRepository 인터페이스 만들기
com.example.firstproject > repository
인터페이스로 구현
리파지토리는 사용자가 직접 구현할 수 도 있지만, JPA에서 제공하는 리파지터리 인터페이슬 활용해서 만들 수 도 있음
ArticleRepositroy에 extends Crud를 입력하면 펼침 목록
CrudRepository<T, ID> 선택 : CrudRepository라는 인터페이스를 상속받는다
CrudRepository 는 JPA에서 제공하는 인터페이스, 이를 상속받아서
엔티티를 관리(생성, 조회, 수정, 삭제) crud 가능 - <> 안에 2개의 제네릭 요소 받기
Article : 관리 대상 엔티티의 클래스의 타입 : 이 예시에서 Article
Long : 관리 대상 엔티티의 대푯값의 타입 : id 의 타입은 Long
이렇게만 작성해도 기본적인 CRUD가 가능하다.
---- 객체 주입하기
ArticleRepository 인터페이스의 구현 객체가 new 없이 사용되었다.
원래같았으면 new ArticleRepositoryImpl() 같이 구현했을 것
하지만 스프링부트에서는 객체 만들 필요가 없음 알아서 객체를 만들어줌
@Autowired 어노테이션을 붙이면 스프링 부트가 생성한 객체를 가져다가 연결함
= 의존성 주입 (DI : Dependeny Injection)
데이터 저장 확인하기
1. article 엔티티가 정말 DB에 테이블로 저장이 되었는가
DTO가 엔티티로 변환이 잘 되었는가?
엔티티가(article) DB에 잘 저장 되는가 - saved.toString()
--- DB 데이터 조회하기
폼 데이터가 DB에 저장이 되었다.
DB에 저장된 데이터는 테이블이라는 틀에 맞춰 관리 됨
CRUD 는 SQL문으로 조작한다.
INSERT, SELECT, UPDATE, DELETE
H2 DB 접속위해
application.properties에 spring.h2.console.enabled = true 추가