# JPA 리파지터리, 데이터 저장하기
## 미션
---
Article을 작성하고, 이를 제출!
![클라우드스터딩-스프링부트-데이터-저장-폼-전달](https://i.imgur.com/FSEBy6A.png)
그 결과를, 데이터베이스로 확인하시오.
![클라우드스터딩-스프링부트-데이터-저장-h2-console-확인](https://i.imgur.com/zpJJmUL.png)
## 개념
---
#### ⭐️ JPA와 리파지터리
데이터를 저장 하려면, DB에 넘겨야 한다. 그런데, 직접 데이터를 넘기기가 쉽지 않다. 서로 사용하는 언어가 다르기 때문이다. 이를 위한 라이브러리가 JPA이다. JPA는 DB와의 소통을, 보다 쉽게한다. 그 핵심이 되는 인터페이스를 리파지터리(repository)라 한다.
![클라우드스터딩-스프링-부트-JPA-리파지터리-repository](https://i.imgur.com/DEZm2LV.png)
#### ⭐️ 엔티티 클래스
리파지터리가 DB와 데이터를 주고 받으려면, 알맞은 규격이 필요하다. ~~편지를 보내려면 편지 봉투가 필요하듯.~~ 이를 엔티티(entity)라 한다.
![클라우드스터딩-스프링-부트-엔티티-클래스-entity](https://i.imgur.com/VEoiTai.png)
#### ⭐️ DB 테이블과 레코드
DB는 데이터를 테이블(table)로 관리한다. 엑셀이라 생각하면 쉽다. 리파지터리에서 엔티티 객체를 보내면, 이를 받아 테이블에 저장한다. 이렇게 엔티티가 테이블로 저장된 것을 레코드(record)라 한다.
![클라우드스터딩-스프링-부트-테이블과-레코드-table-record](https://i.imgur.com/ek6WXLn.png)
#### ⭐️ SQL
DB는 데이터를 관리하는데, SQL 언어를 사용한다. SQL의 가장 기본 명령은 4가지가 있다.
- select: 레코드 조회
- insert: 레코드 추가
- update: 레코드 갱신
- delete: 레코드 삭제
![클라우드스터딩-스프링-부트-데이터베이스-sql-이란](https://i.imgur.com/XTV4jUP.png)
## 튜토리얼
---
#### ⭐️ 최종 구조
![클라우드스터딩-스프링부트-JPA-데이터-저장-구조](https://i.imgur.com/zWc3ATh.png)
#### ⭐️ 리파지터리
1) 인터페이스 생성: "repository/ArticleRepository"
```
public interface ArticleRepository // DB와 소통하는 인터페이스, JPA가 해당 객체를 알아서 만듦!
extends CrudRepository<Article, Long> { // <Article, Long> 의미? 관리 대상은 Article, 대상의 PK는 Long 타입!
}
```
#### ⭐️ 엔티티 클래스
2) 생성: "entity/Article"
```
@Getter // 게터를 자동 생성!
@ToString // toString() 자동 생성!
@NoArgsConstructor // 디폴트 생성자 넣어 줌!
@Entity // DB 테이블에 저장될 클래스 임!
public class Article {
@Id // 이게 ID임! 즉 사람으로 따지면 주민등록 번호! DB에서는 PK(Primary Key)라고 함!
@GeneratedValue(strategy = GenerationType.IDENTITY) // DB에서 자동 관리. 매 생성 시, 1, 2, ... 증가
private Long id;
@Column(length = 100, nullable = false) // 최대 100글자, 비어 있으면 안됨! 추후 SQL 학습
private String title;
@Column(columnDefinition = "TEXT", nullable = false) // 텍스트 타입, 비어있으면 안됨! 추후 SQL 학습
private String content;
@Builder // 빌더 패턴 적용! 추후 설명..!
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
}
```
#### ⭐️ API 컨트롤러
3) 리파지터리에게 데이터를 저장하게 함: "api/ArticleApiController"
```
@Slf4j
@RestController
public class ArticleApiController {
@Autowired // 리파지터리 객체를 알아서 가져옴! 자바는 new ArticleRepository() 해야 했음!
private ArticleRepository articleRepository;
@PostMapping("/api/articles") // Post 요청이 "/api/articles" url로 온다면, 메소드 수행!
public Long create(@RequestBody ArticleForm form) { // JSON 데이터를 받아옴!
log.info(form.toString()); // 받아온 데이터 확인!
// dto(데이터-전달-객체)를 entity(db-저장-객체)로 변경
Article article = form.toEntity();
// 리파지터리에게(db-관리-객체) 전달
Article saved = articleRepository.save(article);
log.info(saved.toString());
// 저장 엔티티의 id(PK)값 반환!
return saved.getId();
}
}
```
#### ⭐️ DTO 클래스
4) 롬복 적용 및 메소드 추가: "dto/ArticleForm"
```
@Data // 생성자(디폴트, All), 게터, 세터, toString 등 다 만들어 줌!
public class ArticleForm {
private String title;
private String content;
// 빌더 패턴으로 객체 생성! 생성자의 변형. 입력 순서가 일치하지 않아도 됨.
public Article toEntity() {
return Article.builder()
.id(null)
.title(title)
.content(content)
.build();
}
}
```
#### ⭐️ 확인하기
5) Article 작성: "localhost:8080/articles/new"
![클라우드스터딩-스프링부트-데이터-저장-폼-전달](https://i.imgur.com/FSEBy6A.png)
6) 로그 확인
![클라우드스터딩-스프링부트-데이터-저장-로그-확인](https://i.imgur.com/pTecRb5.png)
7) application.yaml 작성: "application.properties를 변경"
```
spring:
# DB 설정
h2:
console:
enabled: true
```
8) h2 콘솔 확인
접속 안될 시, 서버 로그에서 해당 정보를 찾아 접속 url 정보를 수정!
```
H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:~블라블라~~'
```
![클라우드스터딩-스프링부트-데이터-저장-h2-console-접속](https://i.imgur.com/YBjcv0v.png)
9) 데이터베이스 레코드 조회
```
SELECT * FROM article;
```
![클라우드스터딩-스프링부트-데이터-저장-h2-console-확인](https://i.imgur.com/zpJJmUL.png)
10) 데이터베이스 레코드 추가
```
INSERT INTO
article(title, content)
VALUES(
'훈밍정음',
'나랏 말쌈이 듕극에 닳아..!'
);
```
11) 레코드 생성 확인
![클라우드스터딩-스프링부트-레코드-생성-확인](https://i.imgur.com/BchFlJq.png)
## 훈련하기
---
- h2-console을 사용. SQL을 직접 사용하여 새로운 글을 추가하시오.
- 작성한 프로젝트 코드를 저장(commit) 하고, 깃허브에 업로드(push) 하시오.
## 면접 준비
---
- DTO와 Entity를 나누는 이유?
- JAP 리파지터리란 무엇, 왜씀?
- 롬복의 장점?
- @Autowired란?
- 데이터베이스 테이블과 레코드의 차이?
- SQL이란?