본문 바로가기

Programing/React

[React + SpringBoot] To-do List 만들기 - (2)

[React + SpringBoot] To-do List 만들기 - (1)

[React + SpringBoot] To-do List 만들기 - (2)

[React + SpringBoot] To-do List 만들기 - (3)

 

 

 

리액트로 만든 Front-end 에 Spring Boot 를 이용하여 Rest Api Server 를 만들어 볼 것이다.

 

우선 Rest Api Server(Back-end) 에서는 '오늘 할 일(To-do)' 목록 출력 및 To-do 추가, 수정, 삭제의 기능만 제어하도록 구성한다.

 

기회가 된다면 사용자 및 그룹을 등록하여 그룹간의 To-do 를 공유할 수 있도록 수정하도록 하겠다.

 


 

1. Spring Initializr 를 이용하여 Project 생성하기

 

프로젝트 생성은 통합 개발 환경(Integrated Development Environment, IDE) 에서도 가능하지만 Spring Initializr 사이트를 이용하여 프로젝트를 생성하는 방법으로 진행해 볼 것이다.

 

Spring Initializr 사이트 바로가기

 

원하는 개발 환경을 설정하여 파일로 다운로드할 수 있다. 아래 링크에서 설정한 내용을 확인할 수 있다.

설정한 환경 확인하기!!

 


 

2. 압축 해제

 

Spring Initializr 사이트에서 개발 환경 설정 후 다운로드 받은 파일을 로컬 PC 내 원하는 경로에 압축 해제한다.

 

원하는 경로에 압축을 해제한다.

 


 

3. 프로젝트 Import

 

Package Explorer 창에서 마우스 우클릭 후 [Import] 를 선택한다.

 

Maven → Existing Maven Projects → [Next] 버튼 클릭

 

[Browse..] 버튼 클릭 → todolist 폴더 선택(압축 해제한 폴더를 선택하면 된다) → [폴더 선택] 버튼 클릭

 

Root Directory 가 설정되고 Projects 에 항목이 추가되면 [Finish] 버튼을 클릭하여 Import 한다.

 

왼쪽 상단 Package Explorer 에 프로젝트가 추가되고, 오른쪽 하단에 프로젝트 관련 설정 파일이 빌드 중인 것을 확인할 수 있다.

 


Check Point 1.

 

간혹 프로젝트 추가 및 빌드가 종료된 후에 아래와 같이 pom.xml 파일의 첫 줄에 에러가 발생하는 경우가 있다.

 

 

Spring Framework 는 빌드 및 컴파일 시 Maven 에 의존하고 있는데 둘 사이의 충돌로 인해 pom.xml 파일에 에러가 발생한 것이다. 프로젝트 시작부터 에러가 발생하여 답답하겠지만 해결 방법은 정말 간단하다.

 

《 1 》 STS 가 최신버전인 경우 "Update Project.." 실행

 

 

《 2  maven plugin 변경 → "Update Project.." 실행

 

// 대략 Line 17 에 properties 태그가 있으며 아래와 같은 코드로 작성되어 있을 것이다.

<properties>

        <java.version>1.8</java.version>

</properties>

 

// 위의 코드를 아래와 같이 수정 후 "Update Project.." 를 실행한다.

<properties>

        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>

        <java.version>1.8</javer.version>

</properties>

 

《 3  spring-boot-starter-parent version 변경 "Update Project.." 실행

 

// 대략 Line 5 에 parent 태그가 있으며 아래와 같은 코드로 작성되어 있을 것이다.

<parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.2.5.RELEASE</version>

        <relativePath/>    <!-- lookup parent from repository -->

</parent>

 

// 위의 코드를 아래와 같이 수정 후 "Update Project.." 를 실행한다.

<parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>2.1.3.RELEASE</version>

        <relativePath/>    <!-- lookup parent from repository -->

</parent>

 


 

4. Package 구성

 

프로젝트의 기본적인 구조를 잡기 위하여 Package 를 생성한다.

 

 


 

5. 도메인 매핑하기

 

우선 데이터베이스에 저장하기 위해서는 유저가 정의한 클래스가 필요하다. 이런 클래스를 Entity 라고 하며, 흔히 말하는 Domain 이라고 생각하면 된다. Entity 는 일반적으로 RDBMS 에서 Table 을 객체화 시킨 것으로 Table 의 이름이나 컬럼들에 대한 정보를 갖게 된다.

 

여기서 도메인 매핑(이 프로젝트는 JPA + H2 Database 사용)은 JPA 를 사용하여 DB 와 도메인 클래스를 연결시켜주는 작업이다. 도메인 클래스를 생성하여 H2 DB 에 매핑하도록 한다.

 

1) DB 에서 도메인을 활용하여 Repository 까지의 데이터 흐름

 

JPA 를 활용한 H2 DB 매핑 구성도

 

2) 도메인 클래스 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.bedmil.todolist.domain;
 
import java.io.Serializable;
import java.time.LocalDateTime;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
 
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table
public class Todo implements Serializable {
 
    /**
     * 
     */
    private static final long serialVersionUID = -947585423656694361L;
    
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column
    private String content;
    
    @Column
    private LocalDateTime createdDateTime;
    
    @Column
    private Boolean isComplete;
 
    @Builder
    public Todo(Long id, String content, LocalDateTime createdDateTime, Boolean isComplete) {
        this.id = id;
        this.content = content;
        this.createdDateTime = createdDateTime;
        this.isComplete = isComplete;
    }
 
    @Override
    public String toString() {
        return "Todo [id=" + id + 
                ", content=" + content + 
                ", createdDateTime=" + createdDateTime + 
                ", isComplete=" + isComplete + "]";
    }
}

 

  • Line 21 : @Entity 어노테이션은 Entity 클래스임을 지정하며 테이블과 매핑된다.
  • Line 22 : @Table 어노테이션은 별도의 이름을 갖는 데이터베이스 테이블과 매핑된다. 기본적으로 @Entity 어노테이션으로 선언된 클래스의 이름은 실제 데이터베이스의 테이블 명과 일치하는 것을 매핑한다. 만약 @Entity 어노테이션이 선언된 클래스 명과 데이터베이스의 테이블명이 다른 경우 @Table(name=" ") 과 같은 방법으로 데이터베이스 테이블과 매핑이 가능하다.
  • Line 30 : @Id 어노테이션은 primary key 를 가지는 변수를 선언하는 것이다.
  • Line 31 : @Column 어노테이션은 선언이 꼭 필요한 어노테이션은 아니며, 기본적으로 멤버 변수명과 일치하는 데이터베이스 컬럼을 매핑한다. 하지만 @Column 에서 지정한 변수명과 데이터베이스의 컬럼명을 서로 다르게 주고 싶은 경우 @Column(name=" ") 과 같은 방식으로 작성하면 된다. 
  • Line 32 : @GeneratedValue(startegy = GenerationType.IDENTITY) 는 기본 키가 자동으로 할당되도록 설정하는 어노테이션이다. 기본 키 할당 전략을 선택할 수 있는데, 키 생성을 데이터베이스에 위임하는 IDENTITY 전략을 사용하였다.

 


 

6. Repository Interface 생성

 

스프링부트에서는 Entity 의 기본적인 CRUD 가 가능하도록 JpaRepository Interface 를 제공한다.

JpaRepository Interface 는 org.springframework.data.jap.repository 패키지의 JpaRepository 라는 인터페이스를 상속하여 만든다. 이 인터페이스는 범용적으로 사용하며, 아래와 같은 형태로 사용된다.

 

public interface 인터페이스명 extends JpaRepository < 엔티티 ID 유형 >

<> 안에는 엔티티 클래스 이름과 ID 필드 타입이 지정된다. 주의할 점은 기본형의 경우 래퍼 클래스를 지정한다는 것이다. 만약 Entity 클래스의 ID 필드 타입을 long 으로 설정한 경우 <Entity 클래스, Long> 으로 작성해야 한다.

 

Spring Data JPA 에서 제공하는 JpaRepository 인터페이스는 상속하기만 해도 되며, 인터페이스에 따로 @Repository 등의 어노테이션을 추가할 필요가 없다.

 

JpaRepository 인터페이스가 제공하는 기능은 다음에 따로 포스팅을 하도록 하겠다.

우선 이 블로그 참조!!

 

아래와 같이 JpaRepository 를 상속받는 TodoRepository 인터페이스를 생성한다.

1
2
3
4
5
6
7
8
9
package com.bedmil.todolist.repository;
 
import org.springframework.data.jpa.repository.JpaRepository;
 
import com.bedmil.todolist.domain.Todo;
 
public interface TodoRepository extends JpaRepository<Todo, Long> {
 
}

 


 

7. 도메인 테스트하기

 

도메인 테스트는 스프링부트에서 지원하는 @DataJpaTest 를 사용하여 진행한다.

@DataJpaTest 는 JPA 에 대한 테스트를 지원하는 어노테이션으로 테스트 시 실행된 변경사항이 실제 DB 에 반영되지 않는다. 이는 테스트를 수행하고 다시 테스트 이전의 데이터로 롤백(Lollback)하기 때문이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.bedmil.todolist;
 
import static org.assertj.core.api.Assertions.assertThat;
 
import java.time.LocalDateTime;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
 
import com.bedmil.todolist.domain.Todo;
import com.bedmil.todolist.repository.TodoRepository;
 
@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaMappingTest {
 
    private final String content = "내용";
    
    @Autowired
    private TodoRepository todoRepository;
    
    @Autowired
    private TestEntityManager entityManager;
    
    private Todo getSaved() {
        Todo todo = Todo.builder()
                        .content(content)
                        .createdDateTime(LocalDateTime.now())
                        .build();
        
        return entityManager.persist(todo);
    }
    
    @Test
    public void test_get() {
        // GIVEN
        Todo todo = getSaved();
        System.out.println("=========================");
        System.out.println(todo.getId());
        System.out.println(todo.getContent());
        System.out.println(todo.getIsComplete());
        System.out.println(todo.getCreatedDateTime());
        System.out.println("=========================");
        Long id = todo.getId();
        
        // WHEN
        Todo savedTodo = todoRepository.getOne(id);
        
        // THEN
        assertThat(savedTodo.getContent()).isEqualTo(content);
        assertThat(savedTodo.getContent()).isEqualTo(todo.getContent());
    }
    
    @Test
    public void test_save() {
        // GIVEN
        Todo todo = Todo.builder()
                        .content("내용1")
                        .isComplete(true)
                        .createdDateTime(LocalDateTime.now())
                        .build();
        
        // WHEN
        Todo savedTodo = todoRepository.save(todo);
        System.out.println("=========================");
        System.out.println(savedTodo.getId());
        System.out.println(savedTodo.getContent());
        System.out.println(savedTodo.getIsComplete());
        System.out.println(savedTodo.getCreatedDateTime());
        System.out.println("=========================");
        
        // THEN
        assertThat(savedTodo.getId()).isGreaterThan(0);
        assertThat(savedTodo.getContent()).isEqualTo("내용1");
        assertThat(savedTodo.getIsComplete()).isEqualTo(true);
    }
    
    @Test
    public void test_delete() {
        // GIVEN
        Todo todo = getSaved();
        System.out.println("=========================");
        System.out.println(todo.getId());
        System.out.println(todo.getContent());
        System.out.println(todo.getIsComplete());
        System.out.println(todo.getCreatedDateTime());
        System.out.println("=========================");
        Long id = todo.getId();
        
        // WHEN
        todoRepository.deleteById(id);
        
        // THEN
        assertThat(entityManager.find(Todo.class, id)).isNull();
    }
}

 

  • Line 17 : @RunWith 어노테이션을 사용하면 JUnit 에 내장된 러너를 사용하는 대신 어노테이션에 정의된 클래스를 호출한다. 또한 JUnit 의 확장 기능을 지정하여 각 테스트 시 독립적인 애플리케이션 컨텍스트(빈의 생성과 관계 설정 같은 제어를 담당하는 IOC 객체를 빈 팩토리라 부르며 이러한 빈 팩토리를 더 확장한 개념이 애플리케이션 컨텍스트이다)를 보장한다.
  • Line 18 : @DataJpaTest 는 스프링부트에서 JPA 테스트를 위한 전용 어노테이션이다. 첫 설계 시 엔티티 간의 관계 설정 및 기능 테스트를 가능하도록 도와준다. 또한 테스트가 끝날 때마다 자동 롤백을 해주어 편리한 JPA 테스트가 가능하다.

JpaMappingTest 클래스에서 JUnit 테스트를 실행 후 결과를 확인한다.

 

JUnit 테스트 성공.

 


 

8. Service 인터페이스 + 클래스 생성

 

사실 이 프로젝트에서는 JpaRepository 에서 제공하는 기능으로 목록, 추가, 수정, 삭제 모두 가능하다.

하지만 JPA 의 기본 기능을 제외한 조회 기능 추가 및 Controller 에서 Repository 를 직접 호출하지 않도록 설계하기 위해서 Service 인터페이스와 클래스를 생성하도록 한다.

Service, ServiceImpl 구조에 대한 고찰

 

JPA 기본 기능을 제외한 조회 기능을 추가하기 위해선 규칙에 맞는 Query 메서드를 추가해야 한다.

method 설명
findBy 로 시작 쿼리를 요청하는 메서드 임을 알린다.
countBy 로 시작 쿼리 결과 레코드 수를 요청하는 메서드 임을 알린다.

Spring Data JPA - Reference Documentation

 

1) TodoService Interface 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.bedmil.todolist.service;
 
import java.util.List;
 
import org.springframework.data.domain.Sort;
 
import com.bedmil.todolist.domain.Todo;
 
public interface TodoService {
 
    List<Todo> getTodos(Sort sort) throws Exception;
    
    void postTodo(Todo todo) throws Exception;
    
    void deleteTodo(Long Id) throws Exception;
    
    Todo findTodoById(Long Id) throws Exception;
}

 

  • Line 11 : Sort 를 파라미터로 가지며, Sort 를 통해 Todo 목록을 정렬하여 가져온다.
  • Line 13 : Todo 를 추가 및 수정한다.
  • Line 15 : Id 에 해당하는 Todo 를 삭제한다.
  • Line 17 : Id 에 해당하는 Todo 를 조회한다.

 

2) TodoService Class 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.bedmil.todolist.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
 
import com.bedmil.todolist.domain.Todo;
import com.bedmil.todolist.repository.TodoRepository;
 
@Service
public class TodoServiceImpl implements TodoService {
 
    @Autowired
    private TodoRepository todoRepository;
    
    @Override
    public List<Todo> getTodos(Sort sort) throws Exception {
        return todoRepository.findAll(sort);
    }
 
    @Override
    public void postTodo(Todo todo) throws Exception {
        todoRepository.save(todo);
    }
 
    @Override
    public void deleteTodo(Long id) throws Exception {
        todoRepository.deleteById(id);
    }
 
    @Override
    public Todo findTodoById(Long Id) throws Exception {
        return todoRepository.findById(Id).orElse(new Todo());
    }
 
}

 

  • Line 35 : Todo 의 id 값을 사용하여 Todo 객체를 반환한다.

 


 

9. TodoController Class 생성

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.bedmil.todolist.controller;
 
import java.time.LocalDateTime;
import java.util.List;
 
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.bedmil.todolist.domain.Todo;
import com.bedmil.todolist.service.TodoService;
 
@RestController
@RequestMapping("/api/todos")
public class TodoController {
 
    @Autowired
    private TodoService todoService;
    
    /*
     *     목록 조회
     */
    @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getTodos() throws Exception {
        List<Todo> todos = todoService.getTodos(Sort.by(Direction.ASC, "id"));
        return ResponseEntity.ok(todos);
    }
 
    /*
     *     등록
     */
    @PostMapping
    public ResponseEntity<String> postTodo(@RequestBody Todo todo) throws Exception {
        todo.setCreatedDateTime(LocalDateTime.now());
        todo.setIsComplete(false);
        todoService.postTodo(todo);
        return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
    }
    
    /*
     *     수정
     */
    @PutMapping("/{id}")
    public ResponseEntity<String> putTodo(@PathVariable("id") Long id) throws Exception {
        Todo todo = todoService.findTodoById(id);
        
        Boolean isComplete = todo.getIsComplete() ? false : true;
        todo.setIsComplete(isComplete);
        todoService.postTodo(todo);
        
        return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
    }
    
    /*
     *     삭제
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<String> deleteTodo(@PathVariable("id") Long id) throws Exception {
        todoService.deleteTodo(id);
        
        return new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
    }
    
}

 


 

10. 테스트를 위한 데이터 생성

 

CommandLineRunner 인터페이스를 이용하여 스프링 부트 구동 시점에 테스트를 위한 데이터를 DB 에 저장을 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.bedmil.todolist;
 
import java.time.LocalDateTime;
import java.util.stream.IntStream;
 
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
 
import com.bedmil.todolist.domain.Todo;
import com.bedmil.todolist.repository.TodoRepository;
 
@SpringBootApplication
public class TodolistApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(TodolistApplication.class, args);
    }
    
    @Bean
    public CommandLineRunner runner(TodoRepository todoRepository) throws Exception {
        return (args) -> {
            IntStream.rangeClosed(110).forEach(index -> todoRepository.save(Todo.builder()
                    .content("오늘 할 일" + index)
                    .createdDateTime(LocalDateTime.now())
                    .isComplete(false)
                    .build())
            );
        };
    }
}

 

  • Line 21 : 스프링은 빈(Bean) 으로 생성된 메서드에 파라미터로 DI(Dependency Injection, 스프링의 주요 특성 중 하나로 주로 의존 관계 주입이라고 한다. 또는 의존 관계를 주입하는게 아니라 단지 객체의 레퍼런스를 전달하여 참조시킨다는 의미로 의존 관계 설정이라고도 한다) 시키는 메커니즘이 존재한다. 생성자를 통해 의존성을 주입시키는 방법과 유사하다. 이를 이용하여 CommandLineRunner 를 빈으로 등록한 후 TodoRepository 를 주입받는다.
  • Line 23 : 자바 8 람다 표현식을 사용하여 깔끔하게 코드를 구현하였다.
  • Line 24 : 페이징 처리 테스트를 위해서 Todo 객체를 빌더 패턴(Builder Pattern, 객체의 생성 과정과 표현 방법을 분리하여 객체를 단계별 동일한 생성 절차로 복잡한 객체로 만드는 패턴)을 사용하여 생성한 후 주입받은 TodoRepository 를 사용하여 Todo 객체를 저장한다. 이때 IntStream 의 rangeClosed 를 사용하여 index 순서대로 Todo 객체 10개를 생성하여 저장한다.

 

데이터가 제대로 저장되어 있는지 확인을 해보자.

TodolistApplication 클래스에서 마우스 우클릭 → Run As.. Spring Boot App 을 선택하여 서버를 구동 후 http://localhost:8080/api/todos 주소에서 데이터를 확인한다.

 

10개의 데이터가 잘 들어가 있음을 확인할 수 있다.

 


 

11. application.properties 설정

 

H2 Database 는 자바로 작성된 RDBMS(관계형 데이터베이스) 관리 시스템으로 매우 빠르고 작은 크기의 데이터베이스라고 생각하면 된다.

주로 메모리에 데이터를 저장하는 용도로 사용되며, 디스크에 데이터를 저장할 수도 있다.

H2 Database 의 특징은 아래와 같다.

  • 매우 빠른 오픈 소스, JDBC Api
  • Embedded(임베디드) 시스템 및 영구 클라이언트 서버 모드(영구 데이터베이스), 인메모리 데이터베이스
  • 브라우저 기반 콘솔 응용 프로그램 지원
  • 작은 설치 공간 : 약 2MB jar 파일 크기

여기선 인메모리 데이터베이스로 휘발성 데이터베이스를 구축하여 서버 재구동시마다 데이터를 리셋하는 방법이 아닌 데이터베이스를 초기화 하지 않는 이상 데이터가 유지되는 영구 데이터베이스(file 로 관리)로 사용할 수 있도록 설정할 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#Encoding UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
 
 
#H2 Web Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
 
 
#DataSource(mem : memory, file : file)
#spring.datasource.url=jdbc:h2:mem:todolistDB
spring.datasource.ulr=jdbc:h2:file:~/tmp/todolistDB
spring.datasource.platform=h2
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
 
 
#JPA
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
 
 
#PORT
server.port=8081

 

  • Line 1 : 스프링부트의 CharacterEncodingFilter 를 이용하여 언어셋을 설정한다.
  • Line 7 : 데이터베이스에 접근할 수 있는 Web Interface 를 사용(Web Console)하기 위한 설정이다. 사실 이 세팅을 해주지 않아도 스프링부트는 아래와 같은 조건이 충족되면 H2 Console 을 자동으로 구성해준다. 또한  path 의 /h2-console 은 Default 값이다.
    • 웹 어플리케이션 프로젝트
    • com.h2database:h2 가 클래스패스에 존재할 경우
    • Spring Boot's developer tools 를 사용할 경우

  • Line 12 : 데이터베이스 연결을 설정한다.
    • Line 13 : 인메모리 데이터베이스 설정
    • Line 14 : file 형태의 영구 데이터베이스 설정
  • Line 21 : JPA 환경 설정
    • Line 22 : JPA 데이터베이스 플랫폼을 지정
    • Line 23 : (Enum) Hibernate 기능으로 데이터 베이스 초기화 전략을 설정
속성 설명
none DB 초기화 관련 작업을 수행하지 않는다.
create SessionFactory 가 시작될 때 기존 스키마(테이블)를 지우고 다시 생성한다. classpath 에서 import.sql 파일이 존재할 경우 파일에 정의된 쿼리를 수행한다.
create-drop 시작은 create 와 동일하지만, SessionFactory 가 종료될 때 스키마를 삭제(테이블 Drop)한다.
update 도메인 객체와 DB 스키마를 비교하여 DB 를 업데이트한다. 즉 변경된 스키마만 반영한다.
validate 도메인 객체가 DB 스키마와 일치하는지 검사한다. 즉 엔티티와 테이블이 정상적으로 매핑되었는지만 확인한다.

 

  • Line 26 : 8080 PORT 를 다른 용도로 사용할 수 있기 때문에, Server PORT 를 8081 로 변경한다.

≪ 참조 ≫ Spring Boot With H2 Database

 


 

지금까지 Spring Boot + JAVA 를 이용하여 Todo-List 의 Rest Api Server 를 개발하였다.

 

다음 포스팅은 Front-end 와 Back-end 연결 설정을 진행할 것이다.

 

 

[ GitHub 주소 ]

https://github.com/JinhoHan/todolist_server

 

 

 

# 계속 하다보면 답이 있겠지...