Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- pointcut
- SpringBoot
- Proxy
- Android
- JPQL
- Greedy
- springdatajpa
- 백준
- db
- 스프링 핵심 원리
- 알고리즘
- jpa
- QueryDSL
- 그리디
- 자바
- Spring Boot
- JDBC
- Servlet
- Thymeleaf
- Exception
- 인프런
- 김영한
- http
- AOP
- 스프링 핵심 기능
- transaction
- 스프링
- spring
- java
- kotlin
Archives
- Today
- Total
개발자되기 프로젝트
Hello JPA 본문
1. JPA 구동방식
- Persistence에서 설정정보 조회
- EntityManagerFactory 생성
- EntityManagerFactory는 애플리케이션 로딩 시 딲! 하나 만 만들어 놔야함.
- EntityManagerFactory 생성위해서는 PersistenceUnitName이 필요
- PersistenceUnitName은 persistence.xml에서 입력한 값이다.
- entityManagerFactory를 만드는 순간 DB랑 연결도 완료됨.
- EntityManager 생성
- 쿼리를 날리기 위해서는 EntityManagerFactory에서 EntityManager를 꺼내야 함.
- DB커넥션을 얻고 종료되는 Transaction 단위마다 entityManager 생성 필요.
-->쉽게말해 DB 커넥션 얻는 것 과 유사.
- 잘 돌아가는지 확인 해 보자. -> entityManager, entityManagerFactory 차례대로 종료.public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); }
- 애플리케이션이 종료되면 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
'인프런 > [인프런] 자바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