Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Hello JPA 본문

1. JPA 구동방식


  • Persistence에서 설정정보 조회
  • EntityManagerFactory 생성
    - EntityManagerFactory는 애플리케이션 로딩 시 딲! 하나 만 만들어 놔야함.
    - EntityManagerFactory 생성위해서는 PersistenceUnitName이 필요
    - PersistenceUnitName은 persistence.xml에서 입력한 값이다.
    - entityManagerFactory를 만드는 순간 DB랑 연결도 완료됨.
    UnitName이 필요 
    persistence.xml
    persistence.xml에서 입력한 이름과 동일하게 입력.
  • EntityManager 생성
    - 쿼리를 날리기 위해서는 EntityManagerFactory에서 EntityManager를 꺼내야 함.
    - DB커넥션을 얻고 종료되는 Transaction 단위마다 entityManager 생성 필요.
     -->쉽게말해 DB 커넥션 얻는 것 과 유사.
     public static void main(String[] args) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
            EntityManager em = emf.createEntityManager();
        }
    - 잘 돌아가는지 확인 해 보자. -> entityManager, entityManagerFactory  차례대로 종료.
    - 애플리케이션이 종료되면 entityManagerFactory 종료해야함.
     public static void main(String[] args) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
            EntityManager em = emf.createEntityManager();
    
            em.close();
            emf.close();
        }​

 

 

 

2. 객체화 테이블을 생성하고 매핑하기.


  • H2 DB에서 테이블 생성
  • 테이블과 매핑 될 객체 만들기
    - @Entity : JPA가 관리할 객체
    - @Id : 데이터베이스 PK와 매핑.
    @Entity
    public class Member {
        
        @Id
        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;
        }
    }​
  • member를 저장해보자.
    - JPA에서 모든 변경은 Transaction 내에서 이루어져야함.
    - em.getTransaction() : entityManager에서 Transaction을 가져옴. 
    - tx.begin() : transaction 시작.
    - em.persist() : 영속화
    - tx.commit() : DB에 반영
 public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

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

        Member member = new Member();
        member.setId(1L);
        member.setName("helloA");

        em.persist(member);
        
        tx.commit();

        em.close();
        emf.close();
    }​
  • 실행 결과 : insert 쿼리 실행됨.
Hibernate: 
    /* insert hellojpa.Member
        */ insert 
        into
            Member
            (name, id) 
        values
            (?, ?)
  • DB에도 반영됨

  • 엇 근데 어느 테이블에 들어가라고 따로 매핑한 적 없는데..?
    - 관례에 따라 매핑됨 ㅋㅋㅋ
  • @Table(name = "")으로 별도 테이블 이름 지정 가능.
  • 필드명과 컬럼 명이 다를 경우 @Column(name = "") 으로 지정 가능.

 

 

3. 코드 수정


  • 하지만 지금 상태 코드는 중간에 문제가 생기면 commit, close가 실행 안될 수 있다.
  • 정석적으로는 transaction을 try-catch 안에다가 넣어주자.
    - 정상적인 경우 commit을 하고 문제가 생기면 rollback 해주자.
    - 💥finally로 모든 작업이 끝나고 entityManager를 종료해주자. 💥
    - entityManager가 내부적으로 DB 커넥션을 물고 돌아감. 꼭 닫아줘야 한다.
    - 애플리케이션이 끝나면 entityManagerFactory 종료
 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(member);

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

        emf.close();
        
    }

 

4. Entity  수정


  • DB에 id=1, name = helloA 엔티티 있는 상태
  • 엔티티 수정의 핵심은 entityManager를 java collection처럼 생각~!
  • 아래와 같은 엔티티 수정은 persist 안해줘도 된다.
  • 왜냐? JPA를 통해 가져온 엔티티는 영속상태 엔티티임.
  • 영속상태 엔티티를 수정하여도 영속상태 유지됨.
  • 따라서 tx.commit 시 변경감지(dirty checking)에 의해 영속상태 엔티티의 변경을 자동으로 update해줌.
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

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

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

            findMember.setName("kimkimkim");
            //em.persist(findMember) 불필요

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

        emf.close();

    }
  • 엔티티를 조회하는 select쿼리 실행
  • 불러온 영속상태 엔티티 수정 후 자동으로 update쿼리 실행됨.
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
        
Hibernate: 
    /* update
        hellojpa.Member */ update
            Member 
        set
            name=? 
        where
            id=?

 

이름 변경됨~~

 

5. Entity 삭제


  • em.remove(삭제할객체)

 

6. 주의


  • EntityManagerFactory는 하나만 생성해서 애플리케이션 전체에 서 공유
    - 웹서버가 올라오는 시점에 딱 하나만생성, DB당 하나 만 생성.
  • EntityManager는 고객 요청이 올때마다 생성했다가 요청 종료시 종료
  • EntityManager는 쓰레드 간에 공유 안함(쓰고 버려)
  • JPA의 모든 데이터 변경은 Transaction안에서 실행!!!!!

 

 

7. JPQL소개


  • 현재 DB의 모든 회원을 검색하고 싶으면...? find만으로는 안되는데...
  • JPQL이 필요!
    - 객체를 대상으로한 SQL
    - 모든 회원 조회 : em.createQuery(query, type)
public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        EntityManager em = emf.createEntityManager();

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

        try{
//            Member findMember = em.find(Member.class, 1L);
            List<Member> memberList = em.createQuery("select  m from Member m", Member.class).getResultList();

            for (Member member : memberList) {
                System.out.println("member id = " + member.id);
                System.out.println("member name = " + member.getName());
            }

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

        emf.close();

    }
Hibernate: 
    /* select
        m 
    from
        Member m */ select
            member0_.id as id1_0_,
            member0_.name as name2_0_ 
        from
            Member member0
            
member id = 1
member name = kimkimkim

 

 

8.JPQL 장점..?


  • paging처리 쉬움.
    - setFirstResult()
    - setMaxResult()
   List<Member> memberList = em.createQuery("select  m from Member m", Member.class)
                    .setFirstResult(5)
                    .setMaxResults(10)
                    .getResultList();

      - 자동으로 limit, offset 처리해줌.

Hibernate: 
    /* select
        m 
    from
        Member m */ select
            member0_.id as id1_0_,
            member0_.name as name2_0_ 
        from
            Member member0_ limit ? offset ?
  • 또한 DB를 바꿔도 dialect에 맞춰 번역해줌. ㄷㄷ

9. JPQL 정리


  • JPA를 사용하면 entity 객체 중심으로 개발
  • 문제는 검색 쿼리임!
  • JPQL 덕분에 검색할 경우 테이블이 아닌 엔티티 객체를 대상으로 검색함
  • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능 ㅎㅎ
  • 애플이케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL 필요.
    -> JPQL은 엔티티 객체를 대상으로 쿼리를 날리기 때문에 DB에 종속적이지 않다.
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
  • SQL문법과 유사
  • JPQL은 엔티티 객체를 대상으로 쿼리 작성
  • SQL은 데이터베이스 테이블을 대상으로 쿼리
  • JPQL은 객체 지향 쿼리
  • SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않음
  • 즉 JPQL은 객체 지향 SQL

 

10. GitHub : 210808 Hello JPA


 

GitHub - bsh6463/JPA

Contribute to bsh6463/JPA development by creating an account on GitHub.

github.com

 

'인프런 > [인프런] 자바ORM 표준 JPA 프로그래밍' 카테고리의 다른 글

플러시, 준영속 상태, 정리  (0) 2021.08.08
영속성 컨텍스트 2  (0) 2021.08.08
영속성 컨텍스트  (0) 2021.08.08
JPA 시작, 프로젝트 세팅  (0) 2021.08.07
JPA?  (0) 2021.08.07
Comments