BE전문가 프로젝트

JPQ의 작동원리와 JPA 애플리케이션 개발 및 JPQL 맛보기 본문

JPA

JPQ의 작동원리와 JPA 애플리케이션 개발 및 JPQL 맛보기

원호보고서 2022. 9. 18. 21:36

JPA 작동원리

1. jpa는 persistence라는 클래스에서 시작한다.

2. META-INF/persistence.xml에서 설정정보를 읽는다.

3. entity ManagerFactory라는 클래스를 만든다.

4. 필요할 때 마다 EntityManager에서 필요할 때 마다 찍어낸 후 돌린다.

 

Entity만들기(Member.class)

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 String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
}
Annotation
@Entity @Entity를 작성해야 jpa가 처음 로딩될 때 jpa를 사용하는 애라는 것을 알게 된다.
@ID Pramary키 값을 의미한다.
@Table("테이블명") 테이블 명을 다르게 사용하고 싶을 때 사용한다.
@Column("컬럼명") 컬럼 명을 다르게 사용하고 싶을 때 사용한다.

 

MainMethod생성

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();
     
    }
}

실제 동작하는 코드를 여기서 작성하게 된다(DB에 저장하거나 불러오는 등)

Application이 종료하게 되면 entityManager와 EntityFactory를 닫아줘야한다.

 

JPA에서는 트랜잭션의 역할이 매우 중요하다

변경되는 모든 작업은 반드시 트랜잭션 안에서 해야한다.

 

주의

  • EntityManager Factory는 웹 서버가 올라오는 시점에 하나만 생성이 된다. 즉 하나만 생성하서 애플리케이션 전체에서 공유 한다.
  • EntityManager 는 고객의 요청이 들어올 때 마다 동작 후 닫아주는 것이다. 쓰레드간에 공유은 절대로 사용해선 안되며 사용 후 닫아줘야 한다.
  • JPA의 모든 데이터 변경은 트랜잭션 안에서 실행한다.

 

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 member = new Member();

            member.setId(1L);
            member.setName("HelloA");

            em.persist("HelloA");

            tx.commit();                                    //트랜잭션 적용
        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }
        
         emf.close();
    }
}

select, update

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 member = em.find(Member.class, 1L);
            member.setName("HelloJPA");
            
            tx.commit();                                    //트랜잭션 적용
        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();  
        }
		
        emf.close();
    }
}

select

find라는 것을 사용하여 데이터를 가져올 수 있다.

 

update

JPA는 데이터를 마치 자바 컬랙션을 다루듯 사용할 수 있게 설계되어있기 때문에 set으로 객체의 정보만 바꿔주면 트랜잭션 commit시에 업데이트 쿼리를 날려준다.

 

JPQL

조건이 붙은 데이터(ex 20세 이상의 남자) 및 join 등 복잡한 쿼리를 이용하여 데이터를 가져오고 싶을 때는 어떻게 해야하는가?

JPA에서는 JPQL을 이용하여 쿼리문을 작성할 수 있다.

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;

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 {
            List<Member> list = em.createQuery("select m from Member as m", Member.class).getResultList();
        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
            emf.close();
        }

    }
}

JPA에서는 DB table대상으로 쿼리를 작성하지 않는다. 우리가 만든 Member 객체에 대해서 쿼리를 작성해야 한다.

 

사용사례

페이징

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;

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 {
            List<Member> list = em.createQuery("select m from Member as m", Member.class)
                    .setFirstResult(1)
                    .setMaxResults(10)
                    .getResultList();
        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
            emf.close();
        }

    }
}

mySQL은 페이징하는 것이 간편한 반면 오라클의 경우 귀찮은 작업들을 해야한다.

하지만 JPQL은 페이징 시 귀찮은 작업들을 각각의 DB에 맞게 알아서 세팅해주기 때문에 따로 작성할 필요가 없다.

 

  • JPA를 사용하면 엔티티 객체를 중심으로 개발이 가능하다.
  • 문제는 검색 쿼리이다. sql문을 이용하여 조건을 설정해줘야 하는데 JPA는 객체지향이기 때문에 JSQL을 통해 entity객체를 대상으로 쿼리를 작성할 수 있다.
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공한다.
  • SQL에서 사용하는 Select, from, Here, Group By, Having, Join을 지원한다.
  • JPQL은 엔티티 객체를 대상으로 쿼리를 작성한다.
  • 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리이다.

'JPA' 카테고리의 다른 글

플러시  (0) 2022.09.25
영속성 관리(JPA 내부 구조)  (0) 2022.09.25
JPA 프로젝트 생성(HelloWolrd) 후 DB 설정  (0) 2022.09.05
JPA란?  (0) 2022.08.14
JPA 탄생배경  (0) 2022.08.03
Comments