728x90

목표

Spring Boot에서 JPA 사용하기

 

환경

  • Framework : Spring Boot 2.6.7
  • Build : Gradle 6.9.2
  • JDK : JDK11

 

할 것 요약

1. build.gradle에 JPA dependency 추가하기

2. application.yml에 JPA 설정 추가하기

3. JPA Entity 생성

4. JPA Repository 생성

5. JPA CRUD API 만들어보기

 

해보기

1. build.gradle에 JPA dependency 추가하기

dependencies {
    // JPA
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

 

2. application.yml에 JPA 설정 추가하기

spring:
  ## JPA Setting Info
  jpa:
    hibernate:
      ddl-auto: create  # option type: create, create-drop, update, validate, none
    properties:
      hibernate:
        diarect: org.hibernate.dialect.H2Dialect  # 쿼리의 기준이 되는 데이터베이스 엔진을 설정합니다.
        show_sql: true  # sql 쿼리를 보여줍니다.
        format_sql: true  # sql query formatting
        use_sql_comments: true  # sql 쿼리의 추가정보를 보여줍니다.

logging:
  level:
    org:
      hibernate:
        type:
          descriptor:
            sql: trace  # query의 ?에 어떤 값이 들어가는지 추적할 수 있는 설정입니다. TRACE Log에 값을 보여줍니다.

spring.jpa.hibernate.ddl-auto 옵션

create 애플리케이션 실행 시 테이블을 모두 제거하고 다시 생성합니다. (drop & create)
create-drop 애플리케이션 실행 시 테이블을 모두 제거하고 다시 생성합니다. 그리고 애플리케이션 종료 시점에 테이블을 모두 제거합니다. (drop & create & drop)
update 애플리케이션 실행 시 변경점만 반영됩니다.
validate 현재 테이블 정보가 entity에 정의된 내용과 동일한지 체크합니다. 다를 경우 경고를 출력하며 애플리케이션을 실행시키지 않습니다.
none 자동생성을 사용하지 않습니다.

 

spring.jpa.properties.hibernate.show_sql: true

 

spring.jpa.properties.hibernate.format_sql: true

 

spring.jpa.properties.hibernate.use_sql_comments: true

 

logging.level.org.hibernate.type.descriptor.sql: trace 설정

 

3. JPA Entity 생성

// Member.java

package com.herojoon.jpaproject.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.sun.istack.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;

import javax.persistence.*;
import java.util.Date;

@SuperBuilder
@NoArgsConstructor
@Setter
@Getter
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})  // JPA에서 lazy관련 에러 날 경우 사용
@Entity  // 객체와 테이블 매핑
@Table(name = "MEMBER")  // 테이블 지정
public class Member {
    @Id  // Primary Key 지정
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // AUTO_INCREMENT 설정 (id값이 null일 경우 자동 생성)
    @Column(name = "ID")  // 컬럼 지정
    private Long id;

    @NotNull
    @Column(name = "NAME")
    private String name;

    @NotNull
    @Column(name = "email")
    private String email;

    @Column(name = "NICKNAME")
    private String nickname;

    @Column(name = "AGE")
    private Integer age;

    @Column(name = "BIRTHDAY")
    private Date birthday;
}

Entity에 정의한 내용으로 테이블이 생성됩니다.

 

4. JPA Repository 생성

// MemberRepository.java

package com.herojoon.jpaproject.repository;

import com.herojoon.jpaproject.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {  // JpaRepository를 상속하여 사용. <객체, ID>
}

 

5. JPA CRUD API 만들어보기

// MemberController.java

package com.herojoon.jpaproject.controller;

import com.herojoon.jpaproject.entity.Member;
import com.herojoon.jpaproject.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RequiredArgsConstructor
@RequestMapping("api/member")
@RestController
public class MemberController {

    private final MemberService memberService;

    /**
     * Member 생성
     *
     * @return
     * @throws ParseException
     */
    @PostMapping("create")
    public ResponseEntity<Member> createMember() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = format.parse("2011-12-03");
        Member member = Member.builder()
                .name("herojoon")
                .email("herojoon432@gmail.com")
                .nickname("heroble")
                .age(10)
                .birthday(date)
                .build();
        Member savedMember = memberService.createMember(member);
        return new ResponseEntity<>(savedMember, HttpStatus.OK);
    }

    /**
     * Member 수정
     *
     * @return
     * @throws ParseException
     */
    @PutMapping("update")
    public ResponseEntity<Member> updateMember() throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = format.parse("2011-12-03");
        Member member = Member.builder()
                .id(1l)
                .name("herojoon2")
                .email("herojoon432@gmail.com")
                .nickname("heroble2")
                .age(10)
                .birthday(date)
                .build();
        Member updatedMember = memberService.updateMember(member);
        if (!ObjectUtils.isEmpty(updatedMember)) {
            return new ResponseEntity<>(updatedMember, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(member, HttpStatus.NOT_FOUND);
        }
    }

    /**
     * Member List 조회
     *
     * @return
     */
    @GetMapping("list")
    public ResponseEntity<List<Member>> getMembers() {
        List<Member> members = memberService.getMembers();
        return new ResponseEntity<>(members, HttpStatus.OK);
    }

    /**
     * Id에 해당하는 Member 조회
     *
     * @param id
     * @return
     */
    @GetMapping("{id}")
    public ResponseEntity<Member> getMember(
            @PathVariable("id") Long id) {
        Member member = memberService.getMember(id);
        return new ResponseEntity<>(member, HttpStatus.OK);
    }

    /**
     * Id에 해당하는 Member 삭제
     *
     * @param id
     * @return
     */
    @DeleteMapping("{id}")
    public ResponseEntity<Long> deleteMember(
            @PathVariable("id") Long id) {
        memberService.deleteMember(id);
        return new ResponseEntity<>(id, HttpStatus.OK);
    }
}
// MemberService.java

package com.herojoon.jpaproject.service;

import com.herojoon.jpaproject.entity.Member;
import com.herojoon.jpaproject.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    /**
     * Member 생성
     *
     * @param member
     * @return
     */
    public Member createMember(Member member) {
        Member savedMember = memberRepository.save(member);  // JpaRepository에서 제공하는 save() 함수
        return savedMember;
    }

    /**
     * Member 수정
     * JPA Repository의 save Method를 사용하여 객체를 업데이트 할 수 있습니다.
     * Entity Member에 @Id로 설정한 키 값이 존재할 경우 해당하는 데이터를 업데이트 해줍니다.
     * 만약 수정하려는 Entity Member 객체에 @Id 값이 존재하지 않으면 Insert 되기 때문에
     * 아래와 같이 업데이트 하고자 하는 Member가 존재하는지 체크하는 로직을 추가하였습니다.
     *
     * @param member
     * @return
     */
    public Member updateMember(Member member) {
        Member updatedMember = null;
        try {
            Member existMember = getMember(member.getId());
            if (!ObjectUtils.isEmpty(existMember)) {
                updatedMember = memberRepository.save(member);  // JpaRepository에서 제공하는 save() 함수
            }
        } catch (Exception e) {
            log.info("[Fail] e: " + e.toString());
        } finally {
            return updatedMember;
        }
    }

    /**
     * Member List 조회
     * 
     * @return
     */
    public List<Member> getMembers() {
        return memberRepository.findAll();  // JpaRepository에서 제공하는 findAll() 함수
    }

    /**
     * Id에 해당하는 Member 조회
     * 
     * @param id
     * @return
     */
    public Member getMember(Long id) {
        return memberRepository.getById(id);  // JpaRepository에서 제공하는 getById() 함수
    }

    /**
     * Id에 해당하는 Member 삭제
     * 
     * @param id
     */
    public void deleteMember(Long id) {
        memberRepository.deleteById(id);  // JpaRepository에서 제공하는 deleteById() 함수
    }
}
 

+ Recent posts