Spring Boot & Rest API (2)

Spring Boot & Rest API (2) - JPA, MySQL

Spring Boot & MySQL 연동

기본적인 REST API 기능은 작성하는 방법을 알았으니 이제 데이터베이스와 연동해보도록 하자

스프링에서 밀고있는 H2 나 가벼운 Database 들도 있지만 조금더 실전에 가깝게 MySQL을 사용해보도록 한다.

또한 데이터베이스 뿐 아니라 JPA 를 이용한 Persistence 에 대해서도 배워보자.

MySQL 설치

우선 실습을 위한 MySQL 셋팅이 되어야 한다.
각 OS 환경에 맞도록 로컬환경에 MySQL 를 설치하거나 Docker 를 이용하여 설치를 한다.

필자는 Docker 를 이용하여 MySQL을 띄웠으며, Host 의 3306 포트와 연결하였다.

또한 테스트용 계정은
username : mysql
password : test
로 하였다.

각 MySQL설치 방법

Docker 로 MySQL 설치 및 접속하기
mac에 MySQL 설치하기
윈도우 10에 MYSQL 설치 방법

MySQL 설정

MySQL 설치가 완료되었으면, 관련된 의존성을 추가하자.

(build.gradle)
dependencies {
    ...
    // Persistence 관리를 위해 JPA 사용
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    // MySQL 연결을 위한 Connector 
    runtimeOnly 'mysql:mysql-connector-java'
    ...
}

다음은 프로젝트 설정으로 jpa 와 데이터베이스 관련 정보를 추가한다.

(application.propertices)
...

// JPA 설정
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

// MySQL 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sample?serverTimezone=UTC&charaterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=test

이상태로 Build 를 하게되면 의존성과 MySQL 설정이 완료된다.

Entity & Repository

JPA 를 이용해 Persistence 를 다룰 경우 Entity 와 Repository 라는 개념이 있다.

우선 Entity 는 Persistence 의 핵심으로 간단하게 말해 다룰 수 있는 데이터 이다.

Persistence를 다루는 여러 글에서 Entity에 대해 나오고 있으니 참고 하도록 하자.

(JPA - 2) 영속성(Persistence) 관리

다음 Repository 는 JPA 를 이용하는 핵심으로 쿼리를 코드 형태로 다룰 수 있도록 도와주는 인터페이스이다.
JPA 는 JPQL 이라는 JPA 전용 쿼리문이 작성된다. 이를 이용해 Database 와 데이터를 주고 받는 것인데 Repository 를 이용할 경우 JPA 에 의해 JPQL 이 자동생성 된다.
물론 JPQL 을 직접 다루는 것도 가능하지만 본 예제에서는 Repository 만을 이용하여 데이터를 다뤄보도록 하겠다.

우선 Entity 부터 보자

(CoffeeMenu.java)
package com.example3.demo.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="coffee_menu")
public class CoffeeMenu implements Menu, Serializable{

    @Id
    @Column(name = "coffee", nullable = false, updatable = false)
    String coffee;

    @Column(name = "coffee_type", nullable = false)
    String type;

    @Column(name = "price", nullable = false)
    int price;

    public String getCoffee() {
        return this.coffee;
    }

    public void setCoffee(String coffee) {
        this.coffee = coffee;
    }

    public String getType() {
        return this.type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getPrice() {
        return this.price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public CoffeeMenu() {

    }

    public CoffeeMenu(String coffee, String type, int price) {
        this.coffee = coffee;
        this.type = type;
        this.price = price;
    }



    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder("{");
        builder.append("\"coffee\":\"");
        builder.append(this.coffee);
        builder.append("\"type\":\"");
        builder.append(this.type);
        builder.append("\",\"price\":");
        builder.append(this.price);
        builder.append("}");
        return builder.toString();
    }
}

getter 와 setter 를 제외하면 디폴트 생성자와 어노테이션들만 추가되었다.

  • Entity
    먼저 @Entity 어노테이션은 해당 클래스는 Entity 이다 라고 명시하는 부분이다.
    이를 통해 JPA 수행시 Entity 로서 다루게된다.
  • Table
    @Table 은 해당 엔티티의 Table 명을 명시하는 것으로 name 에 해당하는 테이블에서 쿼리를 수행한다.
  • Column
    @Column 은 실제 데이터베이스 컬럼명에 해당하는 이름이다. nullable, updatable 등 추가적인 정보를 적어둘 수 있다.
  • Id
    해당 컬럼의 ID 여부이다. Primary 키로 지정할 수 있다.

이렇게해서 실제 수행된 결과이다.

JPA_Create_table

실행 결과를 통해 변환된 쿼리가 어떤 형태인지도 알 수 있다.

다음은 Repository 설정이다.

Repository 는 앞서 설명했 듯이 Controller 등에서 사용하기 위한 인터페이스를 자동 생성한다.
또한 인터페이스만으로도 작동하기 때문에 interface 를 작성하여 어노테이션을 추가하자.

(CoffeeRepository.java)
package com.example3.demo.repository;

import com.example3.demo.entity.CoffeeMenu;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CoffeeRepository extends CrudRepository<CoffeeMenu, String>{
}

이후 기존 ProductController 에서 coffeeRepository를 통해 CRUD 작업이 가능해진다.

(ProductController.java)

...
@RestController
public class ProductController {
    @Autowired
    CoffeeRepository coffeeRepository;

    ...

    @GetMapping(value = "/menu/{count}", produces = "application/json; charset=utf-8")
    public CoffeeMenuList getMenu(
    @PathVariable(value = "count") int count,
    @RequestParam(value = "type", defaultValue = "caffeine") String caffeineType,
    @RequestParam(value = "price", required = true) int price) {
        // coffeeRepository 를 이용 select
        List<CoffeeMenu> list = (List<CoffeeMenu>) coffeeRepository.findAll();
        return new CoffeeMenuList(list);
    }

    @PostMapping(value = "/menu", produces = "application/json; charset=utf-8")
    public String setMenu(
    @RequestBody CoffeeMenu coffeeMenu) {
        // coffeeRepository 를 이용 insert
        coffeeRepository.save(coffeeMenu);
        return "";
    }
    ...
}

이렇게 작성한 후 Postman 을 이용해 테스트 해보자

JPA_postman_post)JPA_postman_get

- - - 이렇게 쉽게 작성한 JPA 만으로 테이블 생성 및 기본적인 데이터베이스 CRUD 작업이 가능해지게 되었다.

엮인글

Spring Boot & 테스트 코드 작성 (1) - JUnit
Spring Boot & 테스트 코드 작성 (2) - Mock, Mockito
Spring Boot & 테스트 코드 작성 (3) - MockMvc
Spring Boot & Rest API (1)
Spring Boot & Rest API (2) - JPA, MySQL


참조

[Spring Boot #24] 스프링 부트 Spring-Data-JPA 연동
[SpringBoot] MySQL 연동
[Spring] Spring MySQL 연동을 위한 설정
JpaRepository 인터페이스 생성
JPA, Hibernate, 그리고 Spring Data JPA의 차이점
(JPA - 2) 영속성(Persistence) 관리
Spring boot에서 DBMS를 연동하는 방법 - JPA 기본편

+ Recent posts