3.1 폼 데이터란
폼 데이터: HTML 요소인 <form> 태그에 실려 전송되는 데이터
<form> 태그는 웹 브라우저에서 서버로 데이터를 전송할 때 사용
어디로(where), 어떻게(how) 보낼지를 적어서 보냄
<form> 태그에 실어서 보낸 데이터는 서버의 컨트롤러가 DTO(Data Transfer Object) 객체에 담아 받음
DTO로 받은 데이터는 최종적으로 데이터베이스에 저장됨
3.2 폼 데이터를 DTO로 받기
입력 폼 만들기
1. src > main > resources > templates 디렉터리에서 articles 디렉터리 생성 후 new.mustache 뷰 페이지 생성
2. 코드 작성
{{>layouts/header}}
<form action="">
<input type="text">
<textarea></textarea>
<button type="submit">Submit</button>
</form>
{{>layouts/footer}}
컨트롤러 만들기
1. src > main > java > com.example.firstproject > controller 패키지에서 ArticleController 클래스 생성
2. 코드 작성
package com.example.firstproject.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller //컨트롤러임을 선언
public class ArticleController {
@GetMapping("/articles/new")
public String newArticleForm(){
return "articles/new"; //뷰 페이지를 반환값으로
}
}
3. localhost:8080/articles/new 페이지에 접속
4. CSS 코드로 디자인 적용 (new.mustache 파일 태그 부분 수정)
{{>layouts/header}}
<form class="container">
<div class="mb-3">
<label class="form-label">제목</label>
<input type="text" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{{>layouts/footer}}
5. 빌드 후 localhost:8080/articles/new 접속
폼 데이터 전송하기
localhost:8080/articles/new 페이지에서 제목, 내용을 입력하고 [Submit] 버튼을 클릭하면 입력한 텍스트만 사라질 뿐 아무 일도 일어나지 않음
→ <form> 태그를 입력할 때 필요한 2가지 정보(where, how)를 주지 않았기 때문
<form> 태그에 2가지 정보 추가
어디에 보낼 지는 action 속성으로, 어떻게 보낼지는 method 속성으로 설정
- action: URL 연결 주소를 적어 action="/articles/create"로 설정
localhost:8080/articles/create 페이지로 폼 데이터를 보낸다는 의미 - method: 속성 값으로 get과 post, 2가지를 설정
여기서는 method="post" 방식으로 설정
<form action="container" action="/articles/create" method="post">
(중략)
</form>
폼 데이터 받기
서버의 컨트롤러가 action, method 속성 정보를 조합하여 사용자가 전송한 폼 데이터를 받도록 함
ArticleController에 createArticle() 메서드 추가
package com.example.firstproject.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@GetMapping("/articles/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("/articles/create") //뷰 페이지에서 post 방식으로 전송했으므로 받을 때도 @PostMapping()으로 받음
public String createArticle(){ //createArticle 메서드 생성
return ""; //형식을 맞추기 위해 return 값에 빈 문자
}
}
@PostMapping() 에서 괄호 안에는 받는 URL 주소를 넣음
new.mustache에서 <form> 태그에 action="/articles/create"로 설정했으므로 괄호 안에도 동일하게 설정
DTO 만들기
1. 새 패키지(com.example.firstproject.dto) 생성
2. dto 패키지에서 ArticleForm.java 클래스(DTO) 생성
3. 입력 폼에서 제목과 내용을 전송하므로 필드 2개 title, content 선언
4. 생성자 추가
5. 폼 데이터 잘 받았는지 확인위해 toString() 메서드 추가
package com.example.firstproject.dto;
public class ArticleForm {
private String title; //제목을 받을 필드
private String content; //내용을 받을 필드
public ArticleForm(String title, String content) { //전송받은 제목과 내용을 필드에 저장하는 생성자 추가
this.title = title;
this.content = content;
}
@Override
public String toString() { //데이터를 잘 받았는지 확인할 toString() 메서드 추가
return "ArticleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
폼 데이터를 DTO에 담기
ArticleController 코드 수정
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm; //ArticleForm 패키지 임포트
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
@GetMapping("/articles/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("/articles/create")
public String createArticle(ArticleForm form){ //폼 데이터를 DTO로 받기
System.out.println(form.toString()); //DTO에 폼 데이터가 잘 담겼는지 확인
return "";
}
}
입력 폼과 DTO 필드 연결하기
new.mustache 코드 수정
{{>layouts/header}}
<form class="container" action="/articles/create" method="post">
<div class="mb-3">
<label class="form-label">제목</label>
<input type="text" class="form-control" name="title"> <!-- DTO의 title 필드와 연결 -->
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" rows="3" name="content"></textarea> <!-- DTO의 content 필드와 연결 -->
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{{>layouts/footer}}
서버 재시작
제목은 abcd, 내용은 1234 입력한 후 [Submit] 버튼 클릭
[Run] 탭에서 title='abcd', content='1234' 출력된 것을 확인할 수 있음
|
3.3 DTO를 데이터베이스에 저장하기
데이터베이스와 JPA
데이터베이스는 데이터를 관리하는 창고로, 줄여서 DB라고 함
DB의 모든 데이터는 행과 열로 구성된 테이블에 저장해 관리
JPA(Java Persistence API): 자바 언어로 DB에 명령을 내리는 도구
JPA의 핵심 도구
- 엔티티: 자바 객체를 DB가 이해할 수 있게 만든 것으로, 이를 기반으로 테이블이 만들어짐
- 리파지터리: 엔티티가 DB 속 테이블에 저장 및 관리될 수 있게 하는 인터페이스
DTO를 엔티티로 변환하기
Article article = form.toEntity(); 입력을 통해 DTO를 엔티티로 변환
빨간색 오류 표시 → 엔티티 클래스인 Article 클래스를 만들어야 함
Article 클래스 만들기
1. Create class 'Article'을 클릭한 후 controller가 아닌 entity로 수정
2. 기본 패키지(com.example.firstproject)아래에 entity 패키지가 만들어짐, 내부에 Article 클래스가 만들어진 것을 확인
3. Article 클래스 코드 작성
package com.example.firstproject.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity //엔티티 선언
public class Article {
@Id //엔티티 대푯값 지정
@GeneratedValue //자동 생성 기능 추가(숫자가 자동으로 매겨짐)
private Long id;
@Column //title 필드 선언, DB 테이블의 title 열과 연결됨
private String title;
@Column //content 필드 선언, DB 테이블의 content 열과 연결됨
private String content;
}
|
4. Article 생성자 추가, toString() 메서드 추가
//Article 생성자 추가
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
//toString() 메서드 추가
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
5. ArticleController에서 Article 오류 표시가 사라졌음을 확인 가능
toEntity() 메서드 추가하기
toEntity() 메서드는 DTO인 form 객체를 엔티티 객체로 변환하는 역할을 함
1. Create method 'toEntity' in 'ArticleForm' 클릭
2. toEntity 메서드에서 DTO 객체를 엔티티로 반환, 전달값은 Article 클래스의 생성자 형식에 맞춰 작성
public Article toEntity() {
return new Article(null, title, content);
}
ArticleController에서 toEntity() 메서드 오류 표시가 사라진 것을 확인할 수 있음
리파지터리로 엔티티를 DB에 저장하기
일단 ArticleController에 리파지터리(articleRepository)가 있다는 가정하에 코드 작성
1. articleRepository.save() 메서드 호출하여 article 엔티티 저장
2. 필드 선언부에 ArticleRepository 타입의 articleRepository 객체 선언
package com.example.firstproject.controller;
import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class ArticleController {
private ArticleRepository articleRepository; // ② articleRepository 객체 선언
@GetMapping("/articles/new")
public String newArticleForm(){
return "articles/new";
}
@PostMapping("/articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
//1. DTO를 엔티티로 변환
Article article =form.toEntity();
//2. 리파지터리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article); // ① article 엔티티를 저장해 saved 객체에 반환
return "";
}
}
리파지터리 만들기
1. com.example.firstproject.repository 패키지 생성
2. repository 패키지에 New → Java Class 선택한 후 Interface 클릭하여 ArticleRepository 생성
3. CrudRepository 인터페이스 상속받음
CrudRepository 를 상속하여 엔티티를 관리(생성, 조회, 수정, 삭제) 할 수 있음
4. CrudRepository에 홑화살괄호(<>)를 붙이고 2개의 제네릭 요소를 받음
- Article: 관리 대상 엔티티의 클래스 타입, 여기서는 Article.
- Long: 관리 대상 엔티티의 대푯값 타입, id의 타입이 Long이므로 Long 입력
package com.example.firstproject.repository;
import com.example.firstproject.entity.Article;
import org.springframework.data.repository.CrudRepository;
public interface ArticleRepository extends CrudRepository<Article, Long> {
}
DB에 데이터를 생성하고, 읽고, 수정하고, 삭제하는 기본 동작을 추가 코드로 구현할 필요 없이 CrudRepository에서 상속받아 사용할 수 있음
ArticleController에서 ArticleRepository를 자동으로 임포트하고 필드 선언문과 save() 메서드의 빨간색 오류 표시가 사라졌음을 확인할 수 있음
객체 주입하기
ArticleRepository 인터페이스의 구현 객체를 new 키워드로 만든 적이 없는데도 articleRepository 객체를 사용하였음
→ @Autowired 어노테이션을 붙이면 스프링 부트가 알아서 미리 생성해 놓은 객체를 가져다가 연결해줌
→ 의존성 주입(DI, Dependency Injection)
데이터 저장 확인하기
article 엔티티가 DB에 테이블로 저장됐는지 확인
1. DTO가 엔티티로 잘 변환되는지 article.toString() 메서드 호출
2. article이 DB에 잘 저장되는지 saved.toString() 메서드 호출
@PostMapping("/articles/create")
public String createArticle(ArticleForm form){
System.out.println(form.toString());
//1. DTO를 엔티티로 변환
Article article =form.toEntity();
System.out.println(article.toString()); //DTO가 엔티티로 잘 변환되는지 확인 출력
//2. 리파지터리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article);
System.out.println(saved.toString()); //article이 DB에 잘 저장되는지 확인 출력
return "";
}
서버 재시작 후 localhost:8080/articles/new 페이지에 접속
위와 같이 입력한 후, [Submit] 버튼 클릭
[Run] 탭에서 위와 같은 결과 확인 가능
ArticleForm{title='가가가가', content='1111'} // 폼 데이터를 받는 객체인 DTO에 title='가가가가', content='1111'이 저장됨 Article{id=null, title='가가가가', content='1111'} // DTO가 엔티티로 변한돼 id=null, title='가가가가', content='1111'이 저장됨 Article{id=1, title='가가가가', content='1111'} //리파지터리가 엔티티를 DB에 저장해 saved 라는 엔티티 변수에 반환함 |
3.4 DB 데이터 조회하기
H2 DB 접속하기
1. src > main > resources 에서 application.properties 파일 열기
2. 파일에 아래와 같이 작성
spring.h2.console.enable=true
3. 바뀐 설정값 반영하기 위해 서버 재시작 후 localhost:8080/h2-console 페이지에 접속
[Connect] 버튼 클릭해도 접속이 안됨
JDBC URL 에 적힌 값이 DB 접근 주소 → 서버 실행할 때마다 바뀌므로 해당 값을 찾아 다시 입력해주어야 함
4. 인텔리제이의 [Run] 탭에서 Ctrl + F 로 jdbc 검색
jdbc:h2:men: … : JDBC H2 DB가 메모리에서 동작하는데 그 주소가 … 라는 의미
메모리 주소는 컴퓨터마다 다르고 서버를 재시작할 때마다 바뀜
해당 문구를 복사한 후 JDBC URL에 붙여 넣고 [Connect] 버튼 클릭하여 DB에 접속
데이터 조회하기
1. ARTICLE 테이블 클릭하면 SELECT * FROM ARTICLE 이 적힌 SQL문 나옴
2. [Run] 클릭 → H2 DB를 설정한 후 서버를 재시작해서 데이터가 날라가 아무런 데이터가 없다고 나옴
데이터는 테이블에 행 단위로 저장되는데 이러한 행 하나하나를 레코드(record) 라고 함
3. 웹 브라우저에서 새 탭을 추가하고 localhost:8080/articles/new 페이지로 이동
제목과 내용 입력한 후 [Submit] 버튼 클릭한 후 DB로 가서 [Run] 클릭하면 입력한대로 레코드가 존재함을 확인할 수 있음
4. SQL문으로 직접 레코드 삽입하기
INSERT 문 사용
INSERT INTO 테이블명(속성명1, 속성명2, 속성명3, ...) VALUES(값1, 값2, 값3, ...);
'백엔드 > 코딩 자율학습 스프링 부트 3 자바 백엔드 개발 입문 1~2장' 카테고리의 다른 글
5장. 게시글 읽기: Read (0) | 2024.12.21 |
---|---|
4장. 롬복과 리팩터링 (0) | 2024.12.21 |
2장. MVC 패턴 이해와 실습 (0) | 2024.11.30 |
1장. 스프링 부트 시작하기 (0) | 2024.11.29 |