본문 바로가기

framework/jpa

[JPA] 기본 사용 방법

pom.xml 설정 추가

    <dependencies>
        <!-- JPA 하이버네이트 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.10.Final</version>
        </dependency>
        <!-- H2 데이터베이스 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>

hibernate-entitymanager를 추가하면 JPA에 필수적인 라이브러리를 가져올 수 있다.

또한 버전의 경우 프로젝트를 만들 때 사용한 spring버전에서 지원하는 hibernate버전을 가져오면 된다.

지원하는 hibernate의 버전의 경우 spring 사이트에서 확인할 수 있다.

hibernate-entitymanager 의존성 추가

javax.xml.bind의 경우 JDK 11 이후에서 JAXB 라이브러리를 내장하고 있지 않기 때문에 발생한 에러를 해결하기 위해 의존성을 추가한다.

출처 : https://roadrunner.tistory.com/645

persistence.xml설정

/resources/META-INF/persistence.xml 파일을 생성 후 내용을 채워야 한다.

<?xml version="1.0" encoding="UTF-8"?>
<!--JPA 버전 2.2 -->
<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">
    <persistence-unit name="hello"> <!--JPA 이름 -->
        <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"/>

            <!-- 옵션 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <property name="hibernate.jdbc.batch_size" value="10"/>
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
        </properties>
    </persistence-unit>
</persistence>
  • hibernate.show_sql(true) : 콘솔창에 SQL을 보여준다
  • hibernate.format_sql(true) : 줄바꿈으로 읽기 편하게 포멧해준다.
  • hibernate.use_sql_comments(true) : 주석문이 같이 출력되며 여기서는 hellojpa.member에 의해 실행되었다.
  • hibernate.jdbc.batch_size(10) 
  • hibernate.hbm2ddl.auto(create) :

dialect

  • dialect는 데이터베이스의 방언(SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능)을 처리한다.
  • JPA는 특정 데이터베이스에 종속하지 않는다.
  • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다.
    • 가변 문자
      • MySQL : VARCHAR
      • Oracle : VARCHAR2
    • 문자열 자르는 함수
      • SQL 표준 : SUBSTRING()
      • Oracle : SUBSTR()
    • 페이징
      • MySQL : LIMIT
      • Oracle : ROWNUM
  • 각각의 데이터베이스가 제공하는 dialect를 사용하여 종속적이지 않는 개발을 한다.

구동 방식

persistence.xml로 설정 정보를 작성한다.

Persistence는 설정 xml 파일을 보고 EntityManagerFactory를 생성한다.

EntityManagerFactory는 필요한 EntityManage를 생성하여 사용한다.


구현

테이블 및 클래스 생성

Member table 생성

create table Member ( 
 id bigint not null, 
 name varchar(255), 
 primary key (id) 
);

 

Member 클래스 생성

package hellojpa;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Member {
    @Id
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Entity는 JPA가 관리할 대상을 설정한다.

@Id는 private Long id가 pk로 사용됨을 설정한다.

입력 - 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) {
    	// Persistence로부터 EntityManagerFactory를 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        
        // EntityManagerFactory로부터 EntityManager를 생성
        EntityManager em = emf.createEntityManager();
        
        // EntityManager로부터 EntityTransaction 생성
        EntityTransaction tx = em.getTransaction();

		// begin() 메소드를 통해 트랜잭션을 시작한다.
        tx.begin();

        try {
        
        	// Insert를 위한 데이터 Member 설정
            Member member = new Member();
            member.setId(1L);
            member.setName("helloA");
			
            // JPA Insert
            em.persist(member);

			// 트랜잭션 커밋
            tx.commit();
            
        } catch (Exception e) {
        
        	// 에러 발생시 롤백
            tx.rollback();
            
        } finally {
        
        	// EntityManager는 내부적으로 데이터베이스의 커낵션을 가지고 동작하기 때문에 사용 후 닫아줘야한다.
            em.close();
            
        }

        emf.close();
    }
}

 

persistence.xml에 작성한 옵션의 결과가 나온다.

Insert 후 콘솔창
DB

조회 - select

try {
    Member findedMember = em.find(Member.class, 1L);
    System.out.println("id : " + findedMember.getId());
    System.out.println("name : " + findedMember.getName());

    tx.commit();
}

EntityManager의 find() 메소드를 통해 Member를 조회한다.

파라미터로는 Member의 클래스와, 조회할 PK 값이 필요하다.

select 후 콘솔

수정 - update

try {
    Member findedMember = em.find(Member.class, 1L);

    findedMember.setName("helloJPA");

    tx.commit();
}

여기서는 EntityManager에서 아이디가 1L인 member를 조회하여 findedMember에 할당하였다.

할당 후에 setName() 메소드를 통해 이름을 변경하였고, 커밋을 실행한다.

JPA는 조회하여 할당한 Member 인스턴스를 관리하고 있기 때문에 값이 변경되면 commit 직에 update를 실행한다.

update 후 콘솔
DB

삭제 - delete

try {
    Member findedMember = em.find(Member.class, 1L);

    em.remove(findedMember);

    tx.commit();
}

삭제시에는 EntityManager의 remove() 메소드를 사용한다.

EntityManager에서 키 값이 1L인 맴버를 조회하여 findedMember로 할당하였고, remove() 하였다.

delete 후 콘솔
DB

 

spring 환경

EntityManagerFactory는 애플리케이션의 DB당 1개만 생성하여 관리한다.

EntityManager는 요청이 올 때 생성하여 사용하고 응답시에 종료한다.

 

Reference

자바 ORM 표준 JPA 프로그래밍(인프런, 김영한)

'framework > jpa' 카테고리의 다른 글

[JPA] 엔티티 매핑 3  (0) 2023.04.23
[JPA] 엔티티 매핑 2  (0) 2023.04.09
[JPA] 엔티티 매핑 1  (0) 2023.04.08
[JPA] JPA 사용 이유 및 개념 정리  (0) 2023.04.07
[JPA] JPA 사용 전 객체지향 프로그래밍의 불편함  (0) 2023.04.07