엔티티 매니저 설정
public class JpaMain {
public static void main(String[] args) {
// 엔티티 매니저 팩토리 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit");
// 엔티티 매니저 생성
EntityManager em = emf.createEntityManager();
...
// 엔티티 매니저 종료
em.close();
// 엔티티 매니저 팩토리 종료
emf.close();
}
}
엔티티 매니저 팩토리
- 생성 시 JPA를 동작시키기 위한 기반 객체를 만들고 JPA 구현체에 따라서는 데이터베이스 커넥션 풀도 생성하므로 생성 비용이 매우 크다. => 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.
- 애플리케이션 종료 시 엔티티 매니저 팩토리도 종료해야 한다.
엔티티 매니저
- 엔티티를 데이터베이스에 CRUD할 수 있다.
- 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드 간 공유 또는 재사용하면 안 된다.
- 사용이 끝난 엔티티 매니저는 반드시 종료해야 한다.
비즈니스 로직
public class JpaMain {
public static void main(String[] args) {
...
try {
tx.begin();
logic(em); // 비즈니스 로직
tx.commit();
...
}
private static void logic(EntityManager em) {
... // MEMBER 테이블에 저장할 member 객체 생성
// 등록
em.persist(member);
// 수정
member.setAge(20);
// 조회(한 건)
Member user1 = em.find(Member.class, id);
log.info("user1 = `{}`", user1);
// 조회(리스트)
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
log.info("members size = {}", members.size());
// 삭제
em.remove(member);
}
}
- em.persist() : 등록
- em.find() : 조회
- em.createQuery().getResultList() : 조회(리스트) => JPQL 사용
- em.remove() : 삭제
- JPA는 엔티티의 변경 사항을 추적하는 기능을 갖추고 있으므로 엔티티의 값을 변경해주기만 하면 자동으로 데이터베이스에 수정 내용이 반영된다.
JPQL
- JPA는 엔티티 객체를 대상으로 검색하기 때문에 데이터베이스 테이블의 모든 데이터를 대상으로 검색하는 것은 사실상 불가능하다. 이러한 경우에 JPA가 제공하는 JPQL(Java Persistence Query Language)을 사용하면 된다.
- JPQL은 SQL과 거의 유사한 문법을 가지고 있지만, 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 질의한다.
- JPQL은 대소문자를 명확하게 구분한다.
- JPQL은 데이터베이스 테이블을 전혀 알지 못한다. => 위의 코드에서 'from Member m'은 MEMBER 테이블이 아닌 엔티티 객체다.
트랜잭션 관리
public class JpaMain {
public static void main(String[] args) {
...
// 엔티티 매니저에서 트랜잭션 API를 받아온다.
EntityTransaction tx = em.getTransaction();
try {
tx.begin(); // 트랜잭션 시작
... // 비즈니스 로직
tx.commit(); // 커밋
...
}
}
- 항상 트랜잭션 안에서 데이터를 변경해야 한다.
전체 코드
@Slf4j
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
tx.begin();
logic(em);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
private static void logic(EntityManager em) {
String id = "user1";
Member member = new Member();
member.setId(id);
member.setUsername("yuri");
member.setAge(30);
em.persist(member);
member.setAge(20);
Member user1 = em.find(Member.class, id);
log.info("user1 = `{}`", user1);
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
log.info("members size = {}", members.size());
em.remove(member);
}
}
'공부 기록 > Java' 카테고리의 다른 글
[이펙티브 자바 3/E] 아이템1 - 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.06.30 |
---|---|
[JPA] 3장 - 영속성 관리 (0) | 2023.06.20 |
[JPA] 1장 - 스프링부트 프로젝트와 H2 데이터베이스 연결하기 (0) | 2023.06.11 |
[Java] 큐(Queue) (0) | 2023.05.12 |
[Java] 문자열(String), 숫자(int, double, float, long, short) 형변환 (0) | 2023.05.04 |