3.1 폼 데이터(form data)
HTML 요소인 <form> 태그에 실려 전송되는 데이터
어디에 어떻게 보낼지도 설정해야 한다.
- action : 어디에 보낼지(/arcitle/create)
- method : 어떻게 보낼지(post)
웹 브라우저 ➡️ 서버로 데이터를 전송할 때 사용한다
- <form> 태그에 실어 보낸 데이터 : 서버의 컨트롤러가 객체에 담아 받는다.
- 객체 : DTO(Data Transfer Object)
- DTO로 받은 데이터는 최종적으로 데이터베이스(DB)에 저장된다.
3.2 폼 데이터를 DTO로 받기
3.2.1 입력 폼 만들기
뷰페이지에 입력 폼 만들면 되므로 templates 디렉토리에 생성
{{>layouts/header}}
<form action=""> <!-- 입력 폼 작성 -->
<input type="text"> <!-- 제목 입력 -->
<textarea></textarea> <!-- 내용 입력 -->
<button type="submit">Submit</button> <!-- 전송 버튼 -->
</form>
{{>layouts/footer}}
3.2.2 폼 데이터 전송하기
컨트롤러까지 만들었는데 submit 버튼 클릭 시 아무 일도 일어나지 않는다.
<form> 태그 입력할 때 필요한 2가지 정보 - 데이터를 어디로, 어떻게 보낼지에 대한 정보를 주지 않았기 때문이다.
// action : 어디에 보낼지
action="/articles/create"
//method : 어떻게 보낼지
// 속성 값으로 get, post 2가지 설정 가능
method="post"
<form class="container" action="/articles/create" method="post">
3.2.3 폼 데이터 받기
// 서버의 컨트롤러가 action, method 정보 조합해 유저가 전송한 폼 데이터 받기
// 뷰 페이지에서 폼 데이터를 post방식으로 전송했으므로 컨트롤러에서 받을 때도 @PostMapping()으로 받는다
@PostMapping("/articles/create")
public String createArticle(){
return "";
}
3.2.4 DTO 만들기
com.example.firstproject에 새 패키지 추가 > java class 생성
입력 폼에서 제목과 내용 전송하니 DTO에도 2개의 필드 필요(title, content)
폼 데이터에 실어 보낸 데이터는 서버의 컨트롤러가 객체(DTO)에 담아 받는다.
- 뷰 페이지 만들기
- 컨트롤러 만들기
- DTO 만들기
- 폼 데이터를 전송받아 DTO 객체에 담기
package com.example.firstproject.dto;
public class ArticleForm {
// 외부에서 직접 수정할 수 없게 private으로 설정
private String title; // 제목 받을 필드
private String content; // 내용을 받을 필드
// 전송받은 제목과 내용을 필드에 저장하는 생성자 추가
public ArticleForm(String title, String content) {
this.title = title;
this.content = content;
}
// 데이터를 잘 받았는지 확인
@Override
public String toString() {
return "ArticleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
3.2.5 폼 데이터를 DTO에 담기
// 뷰 페이지에서 폼 데이터를 post방식으로 전송했으므로 컨트롤러에서 받을 때도 @PostMapping()으로 받는다
@PostMapping("/articles/create")
public String createArticle(ArticleForm form){
// DTO로 만든 클래스 이름이 AtricleForm이므로 ArticleForm 매개변수 타입의 form객체 매개변수로 선언
// form객체의 toString() 메서드 호출 - DTO에 잘 담겼는지 확인
System.out.println(form.toString());
return "";
}
3.2.6 입력 폼과 DTO 필드 연결하기
필드에 값이 들어가려면 new.mustache 입력 폼에 필드명 지정해줘야 입력 폼이 DTO와 연결
<!-- 제목 입력하는 <input> 태그에 속성 추가-->
<input type="text" class="form-control", name="title">
<!-- 내용 입력하는 <textarea> 태그에 속성 추가-->
<textarea class="form-control" rows="3" name="content"></textarea>

입력 후 submit 버튼 클릭하면 IntelliJ 하단 실행창에서 ArticleForm 데이터가 출력된 것을 확인할 수 있다.

요약
- 뷰페이지 만들고 <form>태그의 action 속성으로 데이터를 어디로 보낼지, method로 데이터를 어떻게 보낼지 정의
- 컨트롤러 만들고 @PostMapping 으로 URL 주소를 연결
- 전송받은 데이터 담아 둘 객체인 DTO 만들기
- 컨트롤러에서 폼 데이터를 전송받아 DTO에 담기
✔️ post, get
1. GET 요청: 데이터를 가져올 때 사용
- 서버에서 데이터를 조회할 때 사용
- 웹사이트에서 페이지를 열거나 정보를 검색할 때 GET 요청
- 예를 들어, https://example.com/articles에 접속하면 게시글 목록을 불러오는 요청
2. POST 요청: 데이터를 서버로 보낼 때 사용
- 서버에 새로운 데이터를 추가하거나 변경할 때 POST 요청을 사용
- GET과 다르게, 데이터가 URL에 보이지 않고 요청 본문(body)에 담겨 전송
- 예를 들어, 블로그 글을 작성해서 서버에 저장할 때 POST 요청을 사용
3.3 DTO를 데이터베이스에 저장하기
3.3.1 데이터베이스와 JPA
✔️ 데이터베이스 : 데이터 관리 창고
- 모든 데이터를 행과 열로 구성된 테이블(table)에 저장해 관리
- DB프로그램 : MySQL, Oracle, MariaDB 등 다양한 종류가 있다(여기서는 H2 DB 사용 - 스프링부트 프로젝트 생성 시 추가)
✔️ JPA : DB에 자바로 명령을 내리는 도구
- DB는 자바 언어를 이해하지 못함 (DB는 SQL 언어 사용)
- 데이터를 객체 지향적으로 관리할 수 있게 해줌
- 핵심 도구
- 엔티티(entity) : 자바 객체를 DB가 이해할 수 있게 만든 것인데, 엔티티를 기반으로 테이블이 만들어짐
- 리포지토리(repository) : 엔티티가 DB속 테이블에 저장 및 관리될 수 있게 하는 인터페이스
➡️ DTO를 엔티티로 변환 후 리포지토리를 이용해 엔티티를 DB에 저장
1. DTO를 엔티티로 변환하기
DTO를 엔티티로 변환하려면 엔티티 클래스부터 만들어야 한다.
컨트롤러가 아닌 entity 패키지를 추가한 이유는 컨트롤러와 엔티티를 나눠 관리하기 위해서이다.

// 1. DTO를 엔티티로 변환
Article article = form.toEntity()
// Article.java
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
private String title;
@Column
private String content;
}
- 엔티티임을 선언
- @Entity 붙은 클래스 기반으로 DB에 테이블 생성
- 테이블 이름은 클래스 이름과 동일(Article)
- DTO 코드를 작성할 때처럼 title, content 필드 선언하고 @Column 붙여 테이블의 각 열(column)과 연결
- 엔티티의 대푯값 넣기
- id로 대푯값 선언 후 @Id 붙이기
- @GeneratedValue 붙여 대푯값을 자동으로 생성하게 함
- 대푯값 : 주민등록번호처럼 Article 엔티티 중 제목과 내용이 같은 것이 있어도 대푯값 id로 구분가능
➡️ DB의 컬럼은 id, title, content이다.
Article클래스의 생성자, to_string 메서드 추가해주고, toEntity()메서드를 추가해준다.
public Article toEntity() {
return new Article(null, title, content);
}
}
- toEntity()는 폼 데이터를 담은 DTO객체를 엔티티로 반환한다.
- 전달값은 Article 생성자 형식에 맞춰 작성한다.
- AtricleForm객체에 id정보는 없으므로 id는 null을 입력한다.
2. 리포지토리로 엔티티를 DB에 저장하기
// 2. 리포지토리로 엔티티를 DB에 저장
Article saved = articleRepository.save(article) // article엔티티를 저장해 saved 객체에 받아 옴
리포지토리 만들기
✔️ ArticleRepository 인터페이스를 만들고 JPA 에서 제공하는 리포니토리 인터페이스를 활용해 구현하기
: extends CrudRepository<T, ID> 선택해 CrudRepository 상속받기
✔️ CrudRepository
- 엔티티 관리 : 생성, 조회, 수정, 삭제 가능
- CrudRepository의 <>안에 2개의 제네릭 요소를 받는다.
- 관리 대상 엔티티의 클래스 타입 - 여기서는 Article
- 관리 대상 엔티티의 대푯값 타입 - 여기서는 Long
public interface ArticleRepository extends CrudRepository<Article, Long> {
}
➡️ C, R, U, D 기본 동작을 추가 코드로 구현할 필요 없이 상속받아 사용 가능
객체 주입하기
📍 의존성 주입(DI, Dependency Injection)
스프링부트는 객체를 만들지 않아도 알아서 객체를 만든다.
@Autowired 어노테이션을 붙이면 스프링 부트가 미리 생성해 놓은 객체를 연결해준다.
데이터 저장 확인하기
- DTO가 엔티티로 잘 변환되는지 article.toString() 호출해 확인
- article이 DB에 잘 저장되는지 saved.toString() 호출해 확인


- 폼 데이터 받는 객체인 DTO에 title='가가가가', content='1111' 저장
- DTO의 클래스 타입은 ArticleForm
- DTO가 엔티티로 변환돼 id=null, title='가가가가', content='1111'이 저장
- 엔티티의 클래스 타입은 Article
- 리포지토리가 엔티티를 DB에 저장해 saved라는 엔티티 변수에 반환
- title과 content는 같고 id는 자동으로 설정된 1을 출력
- saved변수는 엔티티 타입이고, 엔티티의 클래스 타입은 Article
3.4 DB 데이터 조회하기
SELECT문과 INSERT문으로 DB에 저장된 데이터 조회하고 삽입하기
CRUD
폼 데이터 ➡️ DTO ➡️ 엔티티 ➡️ 리포지토리 ➡️ DB에 저장
e.g. 위에서 엔티티로 선언한 Article 테이블은 id, title, content 3개의 열로 구성되어 있다.
Article 테이블에는 데이터가 한 행씩 생성(Create)되고, 데이터는 조회(Read), 수정(Upload), 삭제(Delete)할 수 있다.
CRUD 조작은 SQL로 할 수 있다.
- INSERT : 데이터 생성(삽입)(Create)
- SELECT : 조회(Read)
- UPDATE : 수정(Update)
- DELETE : 삭제(Delete)
3.4.1 H2 DB 접속하기
main > resource > application.properties에 spring.h2.console.enabled=true
➡️ H2 DB에 웹 콘솔로 접근할 수 있도록 허용하는 설정

JDBC H2 DB 가 메모리에서 동작하는데 주소가 위의 파란 부분이다라는 의미이다.
jdbc:h2:mem:56ddd92a-6435-4478-9f69-b99cf2efa8df
이 문구를 복사 후 웹 브라우저의 JDBC URL에 붙여 넣고 DB에 접속한다.
3.4.2 데이터 조회하기

RUN을 클릭하면 아무 데이터가 없다고 나오는데 H2 DB를 설정하고 서버를 재시작해 데이터가 날아갔다.
H2 DB는 모든 입출력을 메모리 모드에서 돌리므로 서버를 재시작하면 DB에 저장된 내용이 사라진다.
데이터는 테이블에 행 단위로 저장된다.
✔️ 레코드(record) : 각각의 행

다시 데이터를 넣고 H2 DB에서 Run 하면 데이터가 잘 들어간 것을 확인할 수 있다.
SQL문으로 직접 레코드 삽입하기
INSERT INTO 테이블명(속성명1, 속성명2,,,) VALUES(값1, 값2, 값3,,);

📍 SQL은 가독성 위해 줄바꿈해서 작성하기도 한다.
INSERT
INTO
article
(id, title, content)
VALUES
(3, 'ccccc', '33333');
📌 셀프체크
1. Controller : controller.MemberController.java
package com.example.firstproject.controller;
import com.example.firstproject.dto.MemberForm;
import com.example.firstproject.entity.Member;
import com.example.firstproject.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class MemberController {
@Autowired
private MemberRepository memberRepository;
@GetMapping("/members/new")
public String newMemberForm(){
return "members/new"; // 뷰페이지 주소로 받아야함
}
@GetMapping("/signup")
public String signUpPage(){
return "members/new";
}
// 폼 데이터 받는 함수
// 서버에 데이터 전송 시 DTO를 엔티티로 변환해 리포지토리로 DB에 저장
@PostMapping("/join")
public String joinMembers(MemberForm form){
System.out.println(form.toString());
// 1. DTO를 엔티티로 변환
Member member = form.toEntity();
System.out.println(member.toString());
// 2. 리포지토리로 엔티티를 DB에 저장
Member saved = memberRepository.save(member);
System.out.println(saved.toString());
return "";
}
}
2. DTO : dto.MemberForm.java
package com.example.firstproject.dto;
import com.example.firstproject.entity.Member;
public class MemberForm {
// 외부 수정 안되게 private로 지정
private String email;
private String password;
// 전송받을 제목과 내용을 필드에 저장하는 생성자
public MemberForm(String email, String password){
this.email = email;
this.password = password;
}
//데이터 잘 받았는지 확인
@Override
public String toString() {
return "MemberForm{" +
"email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
public Member toEntity() {
return new Member(null, email, password);
}
}
3. 엔티티 : entity.Member.java
package com.example.firstproject.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column
private String email;
@Column
private String password;
public Member(Long id, String email, String password) {
this.id = id;
this.email = email;
this.password = password;
}
@Override
public String toString() {
return "Member{" +
"id=" + id +
", email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
}
4. 리포지토리 : repository.MemberRepository.java
package com.example.firstproject.repository;
import com.example.firstproject.entity.Member;
import org.springframework.data.repository.CrudRepository;
public interface MemberRepository extends CrudRepository<Member, Long> {
}
'CS > 스프링부트3 자바 백엔드 개발 입문' 카테고리의 다른 글
[게시판 CRUD 만들기] 6장 | 게시판 내 페이지 이동하기 (0) | 2025.02.22 |
---|---|
[게시판 CRUD 만들기] 5장 | 게시글 읽기: Read (0) | 2025.02.22 |
[게시판 CRUD 만들기] 4장 | 롬복과 리팩토링 (0) | 2025.02.21 |
[스프링 부트 개요] 2장 | MVC 패턴 이해와 실습 (0) | 2025.02.20 |
[스프링 부트 개요] 1장 | 스프링 부트 시작하기 (0) | 2025.02.20 |