가자공부하러!

Hibernate(2) - JPA 기본 CRUD 연습 본문

공부/Java

Hibernate(2) - JPA 기본 CRUD 연습

오피스엑소더스 2019. 11. 19. 15:07

소스코드 : https://github.com/HyeongJunMin/SpringBootOnmacOS/tree/master/ex1-hello-jpa

 

**주의 : EntityManagerFactory는 애플리케이션 전체에 하나만 생성해서 공유.

**주의 : EntityManager는 쓰레드간 공유하면 안됨

**주의 : JPA의 모든 데이터 변경은 트랜잭션 안에서 실행해야 함

 

1. 개발환경

  > Mac OS

  > H2 DB (http://h2database.com/html/main.html)

    - 장점 : 웹용 쿼리툴 제공, 시퀀스/AutoIncrement 모두 지원

    - 설치 : 압축풀고 bin에 h2.sh 실행(터미널에서 권한주고 ./h2.sh)

    - 브라우저콘솔에서 접속 안될 때 : JDBC URL 란에 jdbc:h2:~/test입력하고 연결한 다음 종료하고 jdbc:h2:tcp://localhost/~/test로 다시 접속

  > Maven : 스프링부트 디펜던시 버전에 맞는 디펜던시 사용

    - hibernate-entitymanager : JPA 인터페이스를 가지고있음

     - hibernate-core를 사용해야 함

    - h2 : 드라이버 (다운로드 받은 H2버전과 맞는 디펜던시를 사용해야 함)

 

2. JPA 설정하기 - persistence.xml

  > 경로 : src/main/resources/META-INF/persistence.xml

  > 소스코드

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
    <!-- Define persistence unit -->
    <persistence-unit name="hello"><!--보통 데이터베이스 1개당 1개로 설정-->
        <properties>
            <!--필수속성-->
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <!--이론상 JPA는 특정 DB에 종속적이지 않음. 그러나 RDB마다 조금씩 다른 내용들이 있기 마련(페이징, 가변문자타입 등)
            JPA의 방언처리 방법에 대한 속성을 가지는게 hibernate.dialect 40여가지의 dialect 지원-->


            <!--옵션-->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

 

3. 테스트코드

  > 트랜잭션은 아주 중요함

  > 스프링에서 사용하면 활용방법이 더 간단하게 달라짐

  > INSERT 테스트 코드

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {
    public static void main(String[] args){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        //트랜잭션은 아주 중요한 역할을 함
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            //엔티티매니저로 값을 넣고뺌
            Member mem = new Member();
            mem.setId(2L);
            mem.setName("HelloB");
            em.persist(mem);
            tx.commit();
        }catch (Exception e){
            tx.rollback();  //예외 발생 시 트랜잭션 롤
        }finally {
            em.close();
        }
        emf.close();
    }
}

수행된 쿼리를 볼 수 있게 해준 옵션때문에 콘솔창에 나타난 결과

 

  > UPDATE 테스트

   - 값만 바꿨을 뿐인데...

    - JPA를 통해 가져온 엔티티는 JPA가 관리함

    - JPA가 관리하는 엔티티에 변경사항이 생기면 인식해서 commit시에 update쿼리를 생성해서 수행해줌

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaUpdate {
    public static void run(){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try {
            //SELECT문 수행을 통해 조건에 맞는 객체 리턴
            Member findMem = em.find(Member.class, 1L);

            //객체수정 - 자바컬렉션을 다루는 방법과 유사.
            findMem.setName("바뀐이름");

            tx.commit();
        }catch (Exception e){
            tx.rollback();  //예외 발생 시 트랜잭션 롤
        }finally {
            em.close();
        }
        emf.close();
    }
}

수행 전, 후

 

 

Comments