Spring/JPA

JPA 시작하기 - 애플리케이션 개발 & error

느리지만 꾸준하게 2022. 4. 4. 12:43

JpaMain 실행시키면 쿼리가 나온다.

// JpaMain Class

public class JpaMain {

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

        Member member = new Member();
        member.setId(2L);
        member.setName("HelloB");

        em.persist(member);

        tx.commit();

        em.close();

        emf.close();
    }
}

 

 

 

 

persistence.xml

<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
Hibernate: 
    /* insert hellojpa.Member
        */ insert 
        into
            Member
            (name, id) 
        values
            (?, ?)

 

 

  • 회원 등록
  • 회원 수정
  • 회원 삭제
  • 회원 단 건 조회
try {
    Member findMember = em.find(Member.class, 1L);
    System.out.println("findMember.id = " + findMember.getId());
    System.out.println("findMember.name = " + findMember.getName());

    tx.commit();

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

emf.close();

 

쿼리문 

Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
findMember.id = 1
findMember.name = HelloA

 

 

회원 수정을 하자

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 findMember = em.find(Member.class, 1L);
            findMember.setName("HelloJPA");

            tx.commit();

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

        emf.close();
    }
}

 

 

자바 객체에서 값만 바꿨는데 어떻게 쿼리가 나갈까. 변경이 됬는지 안됬는지 JPA가 업데이트 쿼리를 날리게 된다.

언제? tx commit 직전에 날리고 tx이 commit이 된다. 그리고 업데이트 쿼리가 보여지게 된다.

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=?
  • 엔티티 메니저 팩토리는 하나만 생성해서 애플리케이션 전체에서 공유

 

  • 엔티티 매니저는 쓰레드간에 공유 x (사용하고 버려야 한다.)

 

  • JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

 

 

 

JPQL을 써보자.

 

  • EntityManager.find()

 

  • 객체 그래프 탐색(a.getB().getC())

 

  • 나이가 18살 이상인 회원을 모두 검색하고 싶다?

일단 간단하게 JPQL을 작성해보고

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

            for (Member member : result) {
                System.out.println("member.name = " + member.getName());
            }
Hibernate: 
    /* select
        m 
    from
        Member as m */ select
            member0_.id as id1_0_,
            member0_.name as name2_0_ 
        from
            Member member0_
member.name = HelloJPA
member.name = HelloB

 

 

 

 

 

아래와 같이 실행을 하면 limit offset가 반영이 된다.

try {
//            Member findMember = em.find(Member.class, 1L);
            List<Member> result = em.createQuery("select m from Member as m", Member.class)
                    .setFirstResult(5)
                    .setMaxResults(8)
                    .getResultList();

            for (Member member : result) {
                System.out.println("member.name = " + member.getName());
            }
Hibernate: 
    /* select
        m 
    from
        Member as m */ select
            member0_.id as id1_0_,
            member0_.name as name2_0_ 
        from
            Member member0_ limit ? offset ?

 

 

JPQL은 아래와 같이 쓰이는데

  • JPQL로 전체 회원 검색

 

  • JPQL로 ID가 2이상인 회원만 검색

 

  • JPQL로 이름이 같은 회원만 검색

 

  • JPQL은 객체지향 쿼리

 

즉 JPA를 사용해서 엔티티 객체를 중심으로 개발 할 수 있고

  • 문제는 검색 쿼리인데

 

  • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색이 가능하고

 

  • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.

 

  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

참고 : https://www.inflearn.com/course/ORM-JPA-Basic/lecture/21685?tab=community&volume=1.00&quality=1080&speed=1.5 

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

참고:

https://www.inflearn.com/questions/196595

 

오류인지 잘 모르겠습니다.. - 인프런 | 질문 & 답변

안녕하세요  스프링을 이제 조금 알기 시작한 학생입니다... 강의와 같이 입력을 한것 같은데 문제가 발생해버려서, 혼자 해결을 못 하고 있습니다 항상 잘 듣고 있습니다 감사합니다. [사진] 4

www.inflearn.com

 

 

 

 

 

 

 

 

 

 

 

<출처 김영한: 자바 ORM 표준 JPA 프로그래밍 - 기본편 >

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com