JPA CRUD 간단 실습

식빵·2021년 12월 26일
0

JPA 이론 및 실습

목록 보기
5/17

JPA 기본 실습을 위한 준비는 끝났다.

세세한 이론은 이후에 배우기로 하고 지금부터 간단한 CRUD 테스틀 해보자.

ps. 작성한 글을 다시 보니 내용이 길쭉해서 한눈에 안 들어오네요.
될 수 있으면 화면을 zoom out 시키고 보시는 걸 추천합니다 😁



테스트 코드 및 실행 결과

Entity Class

package hello.domain.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.time.LocalDateTime;

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

    @Id
    private Long id;
    private String nickName;
    private Integer age;
    private LocalDateTime signupDate;
}

Entity 클래스란 JPA 를 통해서 관리되는 클래스이고, 실제 DB의 Table과 매핑되는 클래스다.


Junit test code

package hello.basic;

import hello.domain.entity.SignupUser;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.time.LocalDateTime;
import java.util.List;
import java.util.function.Consumer;

@Slf4j
public class JpaBasicTest {

    // 모든 테스트에선 Factory 를 공유해서 사용한다.
    static EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

    @Test
    void testEntitySelect() {
        defaultTestTemplate((em) -> {

            SignupUser user = new SignupUser();
            user.setId(1L);
            user.setAge(23);
            user.setNickName("dailyCode");
            user.setSignupDate(LocalDateTime.now());

            // Create
            em.persist(user);

            // Update
            user.setAge(25);

            // Read - 단건
            SignupUser selectUser = em.find(SignupUser.class, user.getId());
            System.out.println("selectUser : " + selectUser);

            // Read - 한건 이상
            List<SignupUser> users 
            	   = em.createQuery("select su from SignupUser su", SignupUser.class)
                       .getResultList();
            System.out.println("users : " + users);

            // Delete
            em.remove(user);

        });
    }


    // 모든 @Test 에서 아래 같은 흐름으로 코드가 진행된다.
    // 반복되는 코드를 없애기 위해서 콜백(testCallback)을 사용해서
    // 각 @Test 메소드에서는 핵심 로직만 작성하도록 한다.
    private void defaultTestTemplate(Consumer<EntityManager> testCallback) {
        final EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            // 테스트 소스 작성
            testCallback.accept(em);

            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            em.close();
        }
    }

    @AfterAll
    static void AfterAll() {
        emf.close();
    }
}

console result

Hibernate: 
    
    drop table if exists member CASCADE 
Hibernate: 
    
    drop table if exists signup_user CASCADE 
Hibernate: 
    
    create table member (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )
Hibernate: 
    
    create table signup_user (
       id bigint not null,
        age integer,
        nick_name varchar(255),
        signup_date timestamp,
        primary key (id)
    )
Hibernate: 
    /* insert hello.domain.entity.SignupUser
        */ insert 
        into
            signup_user
            (age, nick_name, signup_date, id) 
        values
            (?, ?, ?, ?)
Hibernate: 
    /* update
        hello.domain.entity.SignupUser */ update
            signup_user 
        set
            age=?,
            nick_name=?,
            signup_date=? 
        where
            id=?
Hibernate: 
    /* select
        su 
    from
        SignupUser su */ select
            signupuser0_.id as id1_1_,
            signupuser0_.age as age2_1_,
            signupuser0_.nick_name as nick_nam3_1_,
            signupuser0_.signup_date as signup_d4_1_ 
        from
            signup_user signupuser0_
Hibernate: 
    /* delete hello.domain.entity.SignupUser */ delete 
        from
            signup_user 
        where
            id=?

코드를 실행하니 테이블도 만들어주고, 내가 작성한 java 코드가 실제 DB에 CRUD 되는 것을
확인할 수 있다.



JPA의 실행 흐름

JPA 실행의 흐름 정리해보겠다.

  • 엔티티 매니저 팩토리 생성
    • static EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    • META-INF/persistence.xml 에서 persistence-unit 에 기재한 이름을 가져와서 생성
    • 생성 비용이 큼, 애플리케이션 전체에서 한 번만 생성하고 사용

  • 엔티티 매니저 생성
    • final EntityManager em = emf.createEntityManager();
    • 엔티티 매니저를 실제 데이터베이스에 CRUD 를 행함.

  • 트랜잭션 관리
    • tx.begin();, tx.commit();, tx.rollback();
    • 엔티티 매니저로부터 받아온다 EntityTransaction tx = em.getTransaction();
    • 참고로 JPA 에 의한 데이터 변경시 반드시 트랜잭션 내에서 행해야 한다.

  • CRUD 코드
    • Create: em.persist(user);
    • Read
      • 단건: em.find(SignupUser.class, user.getId());
      • 1건 이상:
        em.createQuery("select su from SignupUser su", SignupUser.class).getResultList();
        (JPQL 이라는 것을 사용한다)
    • Update: user.setAge(25); - 단순히 값만 변경하면 된다!
    • Delete: em.remove(user);


지금까지 정말 간단한 CRUD 를 해봤다.

이후로는

  • 엔티티 매니저가 무엇인지
  • 엔티티 클래스는 어떻게 매핑하는지
  • JPQL 이란 무엇이고 어떻게 쓰는지

등을 배울 것이다.

profile
백엔드를 계속 배우고 있는 개발자입니다 😊

0개의 댓글