본문 바로가기
슬기로운 자바 개발자 생활/스프링 및 자바웹 서비스

JPA 스프링 부트, 마리아디비, 간단예제(Spring Boot and JPA, MariaDB)

by 슬기로운 동네 형 2022. 11. 18.
반응형

JPA 스프링 부트, 마리아디비, 간단예제(Spring Boot and JPA, MariaDB)


준비물 : 마리아디비, 스프링부트, 마리아디비 자바클라이언트, 메이븐, java8

 

마리아DB를 이용 JPA 간단한 사용법을 포스팅합니다. 

테이블 하나 만들고 CRUD (생성,업데이트,삭제,조회) 기능을 구현해봅니다.

 

1. 메이븐

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

 

인텔리j 초기 프로젝트 만들기 설정

 

마리아디비가 이미 설치 되었다고 가정을 하고요.

스프링 부트의 resources\applcation.properties 파일에 마리아디비 커넥션 정보, jpa 설정 정보를 입력합니다.

마리아디비 username, password 는 각자 설정한대로 넣습니다.

# 마리아디비 정보
spring.datasource.url=jdbc:mariadb://localhost:3306/test?characterEncoding=UTF-8
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.username=xxxxx
spring.datasource.password=xxxxx

# Runtime 콘솔 화면에 SQL 쿼리문을 나타낸다.
spring.jpa.show-sql=true

# Runtime 콘솔 화면에 나타나는 SQL 쿼리문을 깔끔하게 정렬해서 나타낸다.
spring.jpa.properties.hibernate.format_sql=true

# JPA 사용 시 초기화 및 생성 전략 설정 (create, update, create-drop, validate)
# 보통 라이브 환경에서는 update, validate를 사용하고 개발시에는 create, create-drop을 사용합니다.
# create : 매번 테이블 생성을 새로 시도합니다.
# update : 변경이 필요한 경우는 alter 명령이 실행되고, 테이블이 없는 경우 create 명령이 실행됩니다.
# create-drop : create와 동일하며 SessionFactory가 내려가면 테이블을 drop 시킵니다.
# validate : update와 동일하게 Object를 검사하지만 스키마는 건드리지 않고 데이터만 변경합니다. 스키마 구조가 다르면 에러를 발생시킵니다.
# none 아무것도 안함.
# @Entity 컴포넌트를 스캔하여, 서버 실행 시 Table "자동 생성" 및 서버 종료 시 Table "자동 삭제"한다.
spring.jpa.hibernate.ddl-auto=create-drop

# spring.datasource.initialization-mode=always 바뀜
# 서버실행시 자동 실행 src/main/resources/data.sql
spring.sql.init.mode=always
spring.jpa.defer-datasource-initialization=true

#jpa 지연 에러로 추가
spring.jackson.serialization..fail-on-empty-beans=false

위의 설정을 보면 스프링 부트 실행시 마리아디비에 스크립트를 이용해서 테이블을 만듭니다. 부트 실행시 tb_country 테이블이 있으면 삭제하고 다시 만듬니다.

 

resources\data.sql 파일에 테이블에 들어갈 insert 스크립트를 적어두었습니다.

 

자바 파일

자바 vo/dto 는 country  이고 마리아디비에 생성될 테이블도 country로 네이밍을 맞춤.

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.*;


@Getter
@Setter
@ToString
@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Integer id;

    private String nation;

    private String lang;

    private String money;

    private int population;
}

인터페이스 CountryRepository를 만듬.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface CountryRepository extends JpaRepository<Country, Integer> {

    public List<Country> findByLangEndingWith(String lang);  //메소드의 이름이 중요 findBy[XXXX]Like 컬럼이 된다.

}

CountryService.java

jpaRepository 클랙스에서 이미 여러가지 메서드들을 제공하네요. 구경만하다가 코딩을 해보니 꽤 편리합니다.

저도 프로젝트하면 복잡한 업무 로직이 없는 기능들은 jpa를 활용하고 싶어지네요.

import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CountryService {

    private final CountryRepository worldRepository;

    public CountryService(CountryRepository worldRepository) {
        this.worldRepository = worldRepository;
    }

    public List<Country> findAll(){
        return worldRepository.findAll();
    }

    public Country getOne(Integer id){
        return worldRepository.getOne(id);
    }

    public void saveWorld(Country world){
        worldRepository.save(world);
    }

    public List<Country> findByLangEndingWith(String lang){
        return worldRepository.findByLangEndingWith(lang);
    }


}

테스트를 위한 컨트롤러 Controller

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Slf4j
public class Controller {


    @Autowired
    private CountryService wordService;

    @GetMapping("/test")
    public String test(){
        log.info("호출했습니다.");
        return "test";
    }

    @GetMapping("/Country")
    public List<Country> CountryList(){
        return wordService.findAll();
    }

    @GetMapping("/CountryOne")
    public Country CountryRowFind(){
        return wordService.getOne(3);
    }

    @GetMapping("/createCountry")
    public Country CountryCreate(){
        Country world = new Country();
        world.setLang("korean");
        world.setMoney("won");
        world.setNation("kor");
        world.setPopulation(5000);
        wordService.saveWorld(world);

        System.out.println("생성됨....");

        return world;
    }

    @GetMapping("/CountryFindByLang")
    public List<Country> langLike(){
        return wordService.findByLangEndingWith("English");
    }
}

스프링 부트 실행시 테이블을 만드는 로그가 출력됨.

스프링부트 실행시 테이블 생성 스크립트가 출력됨.

실행 및 테스트

컨트롤러 호출하면 콘솔창에 SQL이 나올것으로 예상되네요. 오. 파이어폭스 브라우저에서는 josn 이 이쁘게 출력되네요.

select 쿼리 로그가 출력이되는 모습

마리아 디비에가서 한번 조회해봅니다.

마리아디비 조회

이곳저곳에서 DB는 순수하게 자료저장 용으로 사용하고 로직은 자바쪽으로 application 쪽으로 옮겨져 가는 추세인듯합니다. 기술의 탄생이나 발전은 기존 제공되는 서비스의 단점을 보완하고자 이루어지는 듯합니다.

 SI에서는 mybatis 에 plsql 조합이 주류이지만 어째든 개발자라면 이런저런 경험을 해보고 사이트에 맞는 패러다임이나 프레임워크를 사용하는 유연한 사고방식이 필요한듯합니다.

반응형

댓글