# 데이터 등록하기(create)
### 테이블 생성
웹서비스를 통해 만들어진 데이터는 DB를 통해 관리됩니다. 이를 위해서는 먼저 테이블을 생성해 주어야 합니다.
![Imgur](https://i.imgur.com/PeQNOsp.png)
DBMS를 실행하여 아래의 테이블을 생성해줍니다.
```sql
create table books (
id serial primary key,
title varchar(50),
author varchar(50),
image varchar(255)
);
```
생성 후 잘 동작하는지 확인해보세요.
![Imgur](https://i.imgur.com/FqX7hzi.png)
### VO 생성
DB에 저장된 데이터를 스프링으로 가져올때, 어딘가 담아둘 곳이 필요하겠죠? 데이터를 담아둘 그릇인 VO(Value Object)클래스를 생성해 봅시다.
![Imgur](https://i.imgur.com/HF4qhT0.png)
먼저 패키지를 생성한 뒤,
![Imgur](https://i.imgur.com/9mggpye.png)
Book 클래스를 만들고 필드와 게터세터, 그리고 toString() 메소드를 작성해줍니다.
**Book.java**
```java
package com.mycompany.vo;
public class Book {
int id;
String title;
String author;
String image;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
return "Book [id=" + id + ", title=" + title + ", author=" + author + ", image=" + image + "]";
}
}
```
### Mapper 인터페이스 생성
이전 수업에서 MyBatis 라이브러리를 등록하고 설정 했던 내용을 기억하시나요? MyBatis는 디비의 데이터와 VO객체를 맵핑하기 위해 기능를 제공합니다. 이를 **맵퍼(Mapper)**라고 부릅니다.
![Imgur](https://i.imgur.com/nmsk5LQ.png)
해당 위치에 패키지를 생성 후, 클래스를 작성해주세요.
![Imgur](https://i.imgur.com/KGAJzNr.png)
**BookMapper.java**
```java
package com.mycompany.mapper;
public interface BookMapper {
}
```
### Mapper 객체 등록: root-context.xml
`bookMapper`를 생성 및 등록합니다.
**root-context.xml**
```xml
<!-- Maper -->
<bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.mycompany.mapper.BookMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
```
위 xml을 Java 코드로 변환시 다음과 같습니다.
```java
MapperFactoryBean bookMapper = new MapperFactoryBean(mapperInterface, sqlSessionFactory);
```
> xml 파일 수정 후, 서버를 재시작하여 동작여부를 꼭 확인해 주세요.
### 컨트롤러 생성 및 맵퍼 연결
해당 위치에 BooksController를 생성합니다.
![Imgur](https://i.imgur.com/rE14Heo.png)
**BooksController.java**
```java
package com.mycompany.myapp;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class BooksController {
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String index() {
return "books/index";
}
}
```
맵퍼를 필드로 추가 한 뒤, `@Autowired` 어노테이션을 사용하여 DI해주세요.
**BooksController.java**
```java
package com.mycompany.myapp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.mycompany.mapper.BookMapper;
@Controller
public class BooksController {
@Autowired
private BookMapper bookMapper;
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String index() {
return "books/index";
}
}
```
뷰 폴더에 `books` 폴더를 생성후 `index.jsp`페이지를 생성합니다.
![Imgur](https://i.imgur.com/IS6YD0V.png)
**index.jsp**
```jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page pageEncoding="utf-8" session="false"%>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<title>Books</title>
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Books INDEX</h1>
<p>views/books/index.jsp</p>
</div>
</div>
</body>
</html>
```
페이지가 잘 나타나는지 확인해볼까요?
![Imgur](https://i.imgur.com/ogjnsyU.png)
현재까지의 흐름을 그림으로 정리하고 넘어갑시다.
![Imgur](https://i.imgur.com/nWveceP.png)
### 책 등록 페이지 만들기
`index.jsp` 페이지에 도서등록 버튼을 만들어 줍니다.
**index.jsp**
```jsp
...
<body>
<div class="container">
<div class="jumbotron">
<h1>Books INDEX</h1>
<p>views/books/index.jsp</p>
</div>
<a href="<c:url value="/books/new" />"
class="btn btn-lg btn-primary">도서 등록</a>
</div>
</body>
</html>
```
BooksController에 `newBook()` 메소드를 추가하고 이를 도서등록 버튼의 URL과 연결시켜 줍니다.
**BooksController.java**
```java
...
@Controller
public class BooksController {
@Autowired
private BookMapper bookMapper;
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String index() {
return "books/index";
}
@RequestMapping(value = "/books/new", method = RequestMethod.GET)
public String newBook() {
return "books/new";
}
}
```
메소드의 리턴값에 해당하는 뷰 페이지를 생성해줍니다.
**views/books/new.jsp**
```jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page pageEncoding="utf-8" session="false"%>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet">
<title>Books NEW</title>
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Books NEW</h1>
<p>views/books/new.jsp</p>
</div>
<form action="<c:url value="/books" />" method="post">
<div class="form-group form-group-lg">
<label class="control-label">도서 제목</label>
<input name="title" type="text" class="form-control">
</div>
<div class="form-group form-group-lg">
<label class="control-label">저자</label>
<input name="author" type="text" class="form-control">
</div>
<div class="form-group form-group-lg">
<label class="control-label">이미지</label>
<input name="image" type="text" class="form-control">
</div>
<button type="submit" class="btn btn-lg btn-primary">전송</button>
</form>
</div>
</body>
</html>
```
컨트롤러에 `create()` 메소드를 만들고, 폼의 액션 값과 메소드에 맞게 라우터를 설정해줍니다.
**BooksController.java**
```java
@Controller
public class BooksController {
...
@RequestMapping(value = "/books", method = RequestMethod.POST)
public String create(@ModelAttribute Book book) {
System.out.println(book.toString());
return "";
}
}
```
이제 폼데이터가 잘 전달되는지 확인해 봅시다.
![Imgur](https://i.imgur.com/ojmg4aS.png)
title, autor, image 값이 전달되었음을 확인하였습니다.
![Imgur](https://i.imgur.com/YsfeoF4.png)
### 폼 데이터 한글 깨짐 방지
그런데 한글이 깨져서 전달되는 문제가 보입니다. 이를 해결해봅시다. 먼저는 폼 데이터를 받아오는 컨트롤러에서 아래와 같은 코드를 추가해주면 해결 가능합니다.
```
request.setCharacterEncoding("utf-8");
```
하지만 앞으로 만들어질 수 많은 컨트롤러에 이와같은 코드를 적어넣는 것은 비효율적이므로 web.xml파일에 인코딩필터를 추가하여 처리하도록 합니다.
```xml
...
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
```
![Imgur](https://i.imgur.com/u0wiij1.png)
> xml 파일을 설정한 뒤, 서버를 재부팅하여 정상 동작 여부를 확인해주세요.
### 맵퍼를 통한 데이터 저장
폼 데이터도 정상 적으로 전달 되었고 하니, 이제 마무리를 해야겠습니다. 맵퍼를 사용하여 폼 데이터를 DB에 저장해봅시다.
![Imgur](https://i.imgur.com/nmsk5LQ.png)
생각보다 컨트롤러의 메소드 내용은 단순합니다.
```java
package com.mycompany.myapp;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.mycompany.mapper.BookMapper;
import com.mycompany.vo.Book;
@Controller
public class BooksController {
@Autowired
private BookMapper bookMapper;
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String index() {
return "books/index";
}
@RequestMapping(value = "/books/new", method = RequestMethod.GET)
public String newBook() {
return "books/new";
}
@RequestMapping(value = "/books", method = RequestMethod.POST)
public String create(@ModelAttribute Book book) {
bookMapper.create(book);
return "redirect:/books";
}
}
```
마지막으로 `bookMapper.create(book);`를 구현하며 마무리합니다.
```
package com.mycompany.mapper;
import org.apache.ibatis.annotations.Insert;
import com.mycompany.vo.Book;
public interface BookMapper {
@Insert("insert into books (title, author, image) values (#{title}, #{author}, #{image})")
public boolean create(Book book);
}
```
축하합니다~~ DB에 저장이 완료 되었습니다.
![Imgur](https://i.imgur.com/ojmg4aS.png)
![Imgur](https://i.imgur.com/iu8P8BW.png)