출처 : https://www.inflearn.com/course/ORM-JPA-Basic
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
K-개빈 킹 이 수식어가 어울리는 강사, 대한민국에서 사투리가 가장 섹시한 강사, 내 프로젝트에 의존성으로 추가하고 싶은 강사 강의결제를 고민하는 분들께 1) 너무 훌륭한 강의입니다. 무엇보
www.inflearn.com
1. 프로젝트에 dependency 추가
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[5.0,6.0)</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
hibernate와 h2를 사용했습니다.
2. JPA 설정 (resources > META-INF > persistence.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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으로 이름 지정-->
<persistence-unit name="hello">
<properties>
<!-- 사용할 db -->
<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"/>
<!-- hibernate.dialect 40가지 이상의 데이터베이스 방언 지원
방언 : SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
어떤 db를 쓰는지 설정해두면 JPA가 내가 쓰는 db의 말로 알아서 번역해줌.
오라클 쓰면 value에 OracleDialect 사용하면 됨. -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- 옵션 , 옵션들을 잘 쓰면 성능을 향상 시킬 수 있음
show_sql : 콘솔에 쿼리 보여줌
format_sql : 쿼리 포매팅 해줌
use_sql_comments : 주석으로 어느 부분에서 쿼리 실행한건지 알려줌-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<!-- batch_size : 쿼리를 value만큼 모아뒀다가 전송하는 것
<property name="hibernate.jdbc.batch_size" value="10"/>-->
<!--<property name="hibernate.hbm2ddl.auto" value="create" />-->
</properties>
</persistence-unit>
</persistence>
3. Entity 클래스 생성
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "Member") //이렇게 하면 테이블명 매핑됨
public class Member {
@Id
private Long id;
//@Column(name = "username") 이렇게 하면 컬럼명 매핑됨
private String name;
// 생성자
// jpa는 기본 생성자 필수
public Member() {
}
public Member(Long id, String name) {
this.id = id;
this.name = 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;
}
}
4. JPA 기본 사용법
- 저장(insert) : persist
Member member = new Member(1L, "안녕");
em.persist(member);
- 조회(select) : find
Member member = em.find(Member.class, 1L);
System.out.println("member id : " + member.getId());
System.out.println("member name : " + member.getName());
- 수정(update) : setName("변경할 이름")
Member member = em.find(Member.class, 1L);
member.setName("뭉이");
- 삭제(delete) : remove
Member member = em.find(Member.class, 1L);
em.remove(member);
5. JPA를 사용할 때 주의점
1. 객체와 테이블을 올바르게 매핑하고 설계해야함.
데이터베이스 구조가 복잡할 때는 더 중요
2. 영속성 컨텍스트
엔티티를 영구 저장하는 환경이라는 뜻
영속성 컨텍스트는 논리적인 개념, 눈에 보이지 않음.
엔티티 매니저를 통해 영속성 컨텍스트에 접근
영속성 컨텍스트 내부에는 1차 캐시가 있음
persist하면 1차 캐시에 저장됨 이후에 코드에서 db에서 어떤 값을 찾으려고 할 때 1차캐시에서 먼저 찾는다.
1차 캐시에 값이 있다면 db에서 조회하지 않고 1차 캐시에 있는 값을 반환해줌.
1차 캐시에 값이 없다면 db에서 조회함. 그리고 그 값을 1차 캐시에 저장 후 반환.
6. 영속성 컨텍스트의 이점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
7. 엔티티의 생명주기
- 비영속 상태 (new/transient)
객체를 생성만 한 상태, JPA와 전혀 상관 없는 상태
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
- 영속 상태 (managed)
영속성 컨텍스트에 관리되는 상태
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
EntityManager em= emf.createEntityManager();
em.getTransaction().begin();
// 객체를 저장한 상태(영속) : 이 때 db에 저장되는 게 아님
em.persist(member);
// 이 때 쿼리 실행됨
tx.commit();
- 준영속 상태(detaced)
영속성 컨텐스트에 저장되었다가 분리된 상태
// 준영속 : 영속성 컨텍스트에서 지움
em.detach(member);
준영속 상태로 만드는 방법
em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
em.clear() : 영속성 컨텍스트를 초기화
em.close() : 영속성 컨텍스트 종료
- 삭제 (removed)
삭제된 상태
// 삭제 : 객체를 삭제한 상태
em.remove(member);
영속 엔티티의 동일성 보장
Member findMember1 = em.find(Member.class, 100L);
Member findMember2 = em.find(Member.class, 100L);
System.out.println("findMember1 : " + findMember1);
System.out.println("findMember2 : " +findMember2);
System.out.println(findMember2 == findMember1); // true
영속성 컨텍스트(1차 캐시)에 저장하기 때문에 동일하다고 판단함.
엔티티 등록 트랜잭션을 지원하는 쓰기 지연
Member member1 = new Member();
member1.setId(3L);
member1.setName("안녕");
Member member2 = new Member();
member2.setId(4L);
member2.setName("안녕하세요");
// 이 때 쿼리가 실행되는게 아님
em.persist(member1);
em.persist(member2);
// 이 때 쿼리 실행됨
tx.commit();
persist가 실행될 때 1차 캐시에도 저장하고 insert 쿼리를 생성해서 쓰기 지연 SQL 저장소에 저장함.
모아 둔 쿼리들을 트랜잭션 commit() 할 때 실행됨.
엔티티 수정 (변경 감지)
// 값 찾음
Member member = em.find(Member.class, 3L);
// 값 변경
member.setName("zzzzz");
// 이 이후에 em.persist()할 필요 없음. update 쿼리가 자동으로 실행됨.
tx.commit();
수정하라고 명령하지 않아도 자동으로 변경됨.
commit하면 엔티티와 스냅샷을 비교함
1차 캐시 | ||
@id | Entity | 스냅샷 |
"memberA" | memberA | memberA스냅샷 |
"memberB" | memberB | memberB스냅샷 |
최초로 db에서 읽어온 값을 스냅샷으로 저장해놓음.
Entity를 변경하면 jpa가 Entity와 스냅샷을 비교해서 다르다면 update쿼리를 쓰기 지연 sql 저장소에 만들어놓고 쿼리 실행함.
'코딩 > JPA' 카테고리의 다른 글
[JPA] 상속관계 매핑 (0) | 2023.12.04 |
---|---|
[JPA] 다양한 연관관계 매핑 (0) | 2023.12.04 |
[JPA] JPA 연관관계 매핑 (0) | 2023.12.02 |
[JPA] JPA의 엔티티 매핑 (0) | 2023.12.02 |
[JPA] JPA (0) | 2023.11.28 |