- CRUD
- 게시글을 생성(Create)하고 조회(Read)하고 수정(Update)하고 삭제(Delete)하는 것
3.1 폼 데이터란
- 폼 데이터 : HTML 요소인
<form>
태그에 실려 전송되는 데이터 <form>
태그 : 웹 브라우저에서 서버로 데이터를 전송할 때 사용<form>
태그에 실어 보낸 데이터는 서버의 컨트롤러가 객체(DTO)에 담아 받음- DTO(Data Transfer Objech)로 받은 데이터는 DB에 저장
3.2 폼 데이터를 DTO로 받기
3.2.1 입력 폼 만들기
- templates 디렉터리에 articles 디렉터리 생성 후
new.mustache
뷰 페이지 생성
3.2.2 컨트롤러 만들기
- com.example.~ > controller 패키지에
articleController
콘트롤러 생성
3.2.3 폼 데이터 전송하기
<form>
태그에 데이터를 ‘어디로, 어떻게’ 보낼지에 관한 정보 입력- action 속성 : 어디로 보낼지
- method 속성 : 어떻게 보낼지
3.2.4 폼 데이터 받기
- action, method 속성 정보 설정 후 서버의 컨트롤러가 이 정보를 조합하여 사용자가 전송한 폼 데이터를 받도록 설정
ArticleController
코드 수정
3.2.5 DTO 만들기
- DTO(Data Transfer Object) : 컨트롤러에서 폼 데이터를 받을때 DTO에 담아 받음
- controller와 같은 레벨에 dto 패키지 생성 후 dto 패키지에서
ArticleForm.java
파일 생성 : 이 자바 클래스가 DTO가 됨 - 생성자 추가 : 마우스 우클릭 ‘Generate > Constructor’ 후 필드 선택하면 자동으로 생성자 추가
- 폼 데이터를 잘 받았는지 확인하기 위한
toString()
메서드 추가
3.2.6 폼 데이터를 DTO에 담기
ArticleController
코드 수정- 폼에서 전송한 데이터를 createArticle() 메서드의 매개변수로 받기 : ArticleForm(DTO로 만든 클래스 이름) 타입의 form 객체를 매개변수로 선언
- 폼에서 전송한 데이터가 DTO에 잘 담겼는지 확인하기 위해 출력문 추가 : System.out.println()문 사용 form 객체의 toString() 메서드를 호출해 출력
3.2.7 입력 폼과 DTO 필드 연결하기
- 입력 폼에서 전송한 데이터를 DTO로 받기 위해 필드 2개, title과 content 선언 : 이 필드에 값이 들어가려면
new.mustache
입력 폼에 필드명 지정(지정해야 해당 입력 폼이 DTO의 필드와 연결) new.mustache
에 속성 추가 : DTO의 필드명과 동일한 이름을 name의 속성 값으로 써 주면 입력 폼에서 작성한 두 데이터가 DTO의 해당 필드와 연결- 제목을 입력하는
<input>
태그에name="title"
속성 추가 - 내용을 입력하는
<textarea>
태그에name="content"
속성 추가
- 제목을 입력하는
- 서버 재시작 후 브라우저 새로고침하고 제목, 내용 입력 후 Submit 버튼 클릭 시 인텔리제이 하단 실행창 Run탭에 가 보면 ArticleForm의 데이터가 각각 출력됨
과정 요약
- 뷰 페이지(new.mustache) 생성 후
<form>
태그의 action 속성으로 데이터를 어디로 보낼지(action=”/articles/create”), method 속성으로 데이터를 어떻게 보낼지(method=”post”) 정의- 컨트롤러(ArticleController.java) 생성 후 PostMapping 방식으로 URL 주소 연결(@PostMapping(“/articles/create”))
- 전송받은 데이터를 담아 둘 객체인 DTO(ArticleForm.java) 생성
- 컨트롤러에서 폼 데이터를 전송받아 DTO에 담기
3.3 DTO를 데이터베이스에 저장하기
3.3.1 데이터베이스와 JPA
- 데이터 베이스(DB) : 데이터를 관리하는 창고로 데이터를 행과 열로 구성된 테이블에 저장해 관리함
- DB 프로그램 : MySQL, 오라클, 마리아 DB, H2 DB 등 (1장에서 프로젝트 만들 때 추가한 H2 DB 사용 예정)
-
- DB에 데이터를 기록하기 위해서는 SQL이라는 언어를 사용
- DB는 자바 언어를 이해하지 못함 (스프링 부트는 자바언어 사용)
- JPA : 자바 언어로 DB에 명령을 내리는 도구로, 데이터를 객체 지향적으로 관리할 수 있게 해 줌 (1장에서 프로젝트 생성 시 추가함)
- JPA의 핵심 도구
- 엔티티(entity) : 자바 객체를 DB가 이해할 수 있게 만든 것으로, 이를 기반으로 테이블 생성
- 리파지터리(repository) : 엔티티가 DB 속 테이블에 저장 및 관리될 수 있게 하는 인터페이스
- JPA의 핵심 도구
3.3.2 DTO를 엔티티로 변환하기
ArticleController.java
에는 ‘articles/create’주소로 URL 요청이 들어왔을 때 폼 데이터를 받아 출력하는 코드 존재
: 여기에 DTO를 엔티티로 변환하고 리파지터리로 엔티티를 DB에 저장하는 코드 작성- DTO를 엔티티로 변환하기 위해 form 객체의 toEntity()라는 메서드를 호출해서 그 반환값을 Article 타입의 article 엔티티에 저장
: Article 클래스와 toEntity() 메서드가 필요함(DTO를 엔티티로 변환하려면 엔티티 클래스 필요(Article 클래스 = 엔티티 클래스))- Article 클래스 만들기
- 빨간색으로 표시된 Article 클래스에 마우스를 올리고 Alt + Enter > 목록에서 Create class ‘Article’ 선택 (클래스 만들기 창에서 패키지 생성 위치를 기본 패키지(com.example.~) 아래로 설정하고 .controller > .entity로 수정)
-
- Article 클래스(
Article.java
) 코드 작성 @Entity, @Column, @GeneratedValue
- Article 클래스(
-
- Article 객체의 생성 및 초기화를 위해 생성자 추가
- content 필드 아래에서 우클릭 ‘Generate > Constructor’
- Article 객체의 생성 및 초기화를 위해 생성자 추가
-
- toString() 메서드 추가
- 생성자 아래에서 우클릭 ‘Generate > toString()’
- toString() 메서드 추가
- entity 패키지에 Article 클래스 임포트 확인됨
- toEntity() 메서드 추가하기
- toEntity() 메서드 : DTO인 form 객체를 엔티티 객체로 변환하는 역할(return new Article())
- 전달값은 Article 클래스의 생성자 형식에 맞게 작성 (생성자 :
Article.java
확인)- id, title, content를 매개 변수로 받음
- ArticleForm 객체에 id 정보는 없으므로 첫 번째 전달값은 null, 두 번째 전달값은 title, 세 번째 전달값은 content
- Article 클래스 만들기
controller가 아닌 entity 패키지를 추가하는 이유
- 컨트롤러와 엔티티를 나누어 관리하기 위해
: 새로 만들 Article 클래스는 entity 패키지에 저장
@Id가 빨간색으로 표시될 경우
- 마우스 올린 후 Alt + Enter 누르고 Id(jakarta.persistence) 선택
3.3.3 리파지터리로 엔티티를 DB에 저장하기
articleRepositoyy.save() 메서드
를 호출해 article 엔티티 저장save() 메서드
는 저장된 엔티티를 반환하므로 이를 Article 타입의 saved라는 객체를 받아옴
- 필드 선언부에 ArticleRepository 타입의
articleRepository
객체 선언
save() 메서드
및 필드 선언부의ArticleRepository
가 빨간색으로 뜨며 인식되지 않음 : 해당 리파지터리가 없기 때문에
- 리파지터리 생성
com.example.~
에서 Package 새로 생성 :com.example.~.repository
로 생성- 패키지 생성 후 Java Class 생성 : Interface > ArticleRepository
- CrudRepository라는 인터페이스 상속받는 명령어 작성 및 제네릭 요소 받기
- Article : 관리 대상 엔티티의 클래스 타입 (여기서는 Article)
- Long : 관리 대상 엔티티의 대푯값 타입 (Article.java파일에서 id를 대푯값으로 지정함 > id타입은 Long이므로 Long 입력)
- ArticleRepository는 CrudRepository가 제공하는 기능을 별도 정의 없이 사용 가능
- DB에 데이터를 생성(Create), 읽기(Read), 수정(Update), 삭제(Delete)하는 기본 동작을 추가 코드 없이 CrudRepository에서 상속받아 사용
ArticleController.java
위쪽에import com.example.~.repository.ArticleRepository;
자동 입력 및 필드 선언문과save() 메서드
빨간색 오류 표시 사라짐
- 객체 주입하기
- 의존성 주입 : 스프링 부트에서 제공하는 어노테이션으로 스프링 부트가 만들어 놓은 객체를 가져와 주입해 줌 (하나의 객체가 다른 객체의 의존성을 제공하는 테크닉)
@Autowired
: 스프링 부트가 미리 생성해놓은 객체를 알아서 가져와 연결해 줌
- 데이터 저장 확인하기 (article 엔티티가 DB에 테이블로 저장됐는지 확인)
- DTO가 엔티티로 잘 변환되는지
article.toString() 메서드
를 호출해 확인 - article이 DB에 잘 저장되는지
saved.toString() 메서드
를 호출해 확인
- DTO가 엔티티로 잘 변환되는지
- 서버 재시작 > 페이지 접속 후 내용 입력 > Submit > 인텔리제이 Run 탭 확인
- 폼데이터를 받는 객체인 DTO에
title='가가가가', content='1111'
저장 : DTO의 클래스 타입은 ArticleForm - DTO가 엔티티로 변환돼
id=null, title='가가가가', content=`11111`
저장 : 엔티티의 클래스 타입은 Article - 리파지터리가 엔티티를 DB에 저장해 saved라는 엔티티 변수에 반환
- saved 변수에 저장된 결과
- title과 content는 똑같고 id는 자동으로 설정된 1 출력
- saved 변수는 엔티티 타입, 엔티티의 클래스 타입은 Article
- saved 변수에 저장된 결과
- 폼데이터를 받는 객체인 DTO에
3.4 DB 데이터 조회하기
- DB에 저장된 데이터는 테이블이라는 틀에 맞춰 관리됨
- 테이블 : 행과 열로 구성
- ex_앞에서 엔티티로 선언한 Article의 테이블 : id, title, content라는 3개의 열로 구성
- 테이블에는 데이터가 한 행씩 생성(Create) : 채워진 데이터는 조회(Read), 수정(Update), 삭제(Delete)할 수 있는데 이러한 CRUD 조작은 SQL이라는 언어로 수행
- SQL 문법
- 데이터 생성(삽입) : INSERT 문
- 조회 : SELECT 문
- 수정 : UPDATE 문
- 삭제 : DELETE 문
3.4.1 H2 DB 접속하기
- H2 DB에 접속하기 위해 필요한 기본 설정
src > main > resources
에application.properties
파일 열기spring.h2.console.enable=true
작성 : H2 DB에 웹 콘솔로 접근할 수 있도록 허용하는 설정- 바뀐 설정값을 반영하기 위해 서버 재시작 후
localhost:8080/h2-console
페이지 접속 - JDBC URL에 적힌 값 : DB 접근 주소 > 이 값은 서버 실행할 때마다 변경되므로 값을 찾아서 다시 입력해줘야함
- 인텔리제이 Run 탭에서
ctrl + f
눌러 jdbc 검색jbbc:h2:mem:~
: ‘JDBC H2 DB가 메모리에서 동작하는데 그 주소가 ~이다’라는 의미- ’~’에 해당하는 메모리 주소는 컴퓨터마다 다르고 서버를 재시작할 때마다 바뀜
- 이 문구를 복사 후 JDBC URL에 붙여넣고 Connect 버튼을 클릭해 DB 접속
3.4.2 데이터 조회하기
- DB 화면 오른쪽에서 ARTICLE 테이블을 펼치면 열 속성으로 ID, CONTENT, TITLE이 있다고 표시됨
- 테이블에 데이터 저장됐는지 확인
- ARTICLE 테이블을 클릭하면
SELECT * FROM ARTICLE
이라 적힌 SQL 문 표시- SELECT 문 : 테이블의 속성을 조회하는 명령으로 속성명 대신 *를 사용하면 모든 속성을 조회하라는 뜻
형식 : SELECT 속성명 FROM 테이블명;
- ‘Run’ 클릭 시 데이터가 없다고 나오는데 이는 앞에서 H2 DB를 설정한 후 서버를 재시작해서 데이터가 날라간 것 (H2 DB는 모든 입출력을 메모리 모드에서 돌리기 때문에 서버를 재시작하면 DB에 저장된 내용이 사라짐)
- ARTICLE 테이블을 클릭하면
SQL
- SQL의 명령문은 대소문자 구분 x
- 테이블명과 속성명은 소문자로 작성하기를 권장 : SQL 기본 키워드와 구분하기 위해
- SQL의 각 명령문은 마지막 세미콜론(;)을 넣어 구분
- 게시판에 내용을 입력해 DB 테이블에 저장하기 : 테이블에 행 단위로 저장
= 행 하나하나를레코드
라고 함- 웹 브라우저 새 탭에
localhost:8080/articles/new
로 이동- 제목, 내용 입력 후 Submit : 한번 더 반복
- DB로 가서 ‘Run’ 클릭 시 레코드 2개가 들어간 것을 확인할 수 있음
- 웹 브라우저 새 탭에
- SQL 문으로 직접 레코드 삽입하기 : INSERT 문 사용
- DB 입력창에 SQL문을 지우고 INSERT문을 작성후 Run하면 1건이 업데이트됐다고 표시됨
- Clear을 클릭해 코드를 모두 지우고
SELECT * FROM article;
작성 후 Run : 데이터가 잘 삽입된 것을 확인할 수 있음
형식 : INSERT INTO 테이블명(속성명1, 속성명2, 속성명3, …) VALUES(값1, 값2, 값3, …);
SQL 문 작성 형식
- SQL 문은 가독성을 위해 줄바꿈해서 작성하기도 함
1
2
3
4
5
6
7
8
// 가독성을 위한 SQL 문 작성 형식
INSERT
INTO
article
(id, title, content)
VALUES
(3, 'cccc', '3333');