1. 엔티티 매니저 팩토리 생성하기
JPA를 시작하기 위해선 엔티티 매니저 팩토리를 생성해야 하므로
설정 정보(persistence.xml)를 통해 엔티티 매니저 팩토리를 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("영속성 유닛명");
EntityManagerFactory는 인터페이스이기 때문에 이를 구현한
Persistence 클래스의 createEntityManagerFactory 메서드를 사용해 엔티티 매니저 팩토리 생성
하이버네이트 같은 JPA 구현체들은 팩토리 생성 시 커넥션풀도 생성
엔티티 매니저 팩토리는 생성 비용이 크기 때문에 한 번만 생성하고 공유해서 사용해야 함
2. 엔티티 매니저 생성하기
엔티티 매니저 팩토리를 통해 엔티티 매니저를 생성
JPA의 기능 대부분을 엔티니 매니저가 제공 (CRUD)
EntityManager em = emf.createEntityManager();
내부에 데이터소스를 유지하며 데이터베이스와 통신하는 역할로 가상의 데이터베이스라고 볼 수 있음
데이터베이스 연결이 필요한 시점에만 커넥션을 얻음 (보통 트랜잭션 시작 시 커넥션 획득)
동시성 문제가 생기기 때문에 엔티티 매니저를 스레드 간에 공유/재사용하면 안됨
3. 트랜잭션 생성 및 사용
데이터의 변경은 항상 트랜잭션 안에서 이루어져야 함
트랜잭션은 엔티티 매니저를 통해 받아올 수 있음
EntityTransaction tx = em.getTransaction();
트랜잭션과 예외 처리를 통해 효율적인 데이터 처리를 할 수 있음
try {
tx.begin(); //트랜잭션 시작
crud(엔티티매니저); //CRUD 작업수행
tx.commit();//트랜잭션 커밋
} catch (Exception e) { //작업 실패 시
e.printStackTrace();
tx.rollback(); //트랜잭션 롤백
} finally {
em.close(); //엔티티 매니저 종료
}
begin 메서드를 통해 트랜잭션을 시작한 후, 필요한 CRUD 작업을 수행한다.
작업이 정상적으로 수행되지 못한 경우에는 예외가 발생하여 rollback 메서드를 통해 작업 내용이 롤백되고,
작업이 정상적으로 수행된다면 commit 메서드를 통해 작업 내용을 반영한다.
엔티티 매니저는 사용이 끝났으면 항상 종료시켜야 하기 때문에
반드시 실행되는 finally 영역에서 종료시켜준다.
4. CRUD
새로운 엔티티를 추가(INSERT) 하려는 경우
추가하고자 하는 테이블의 객체(엔티티)를 생성
Member member = new Member(); // 회원 엔티티 생성
해당 엔티티의 Setter 메서드를 통해 엔티티의 값을 수정
member.setId("id1");
member.setUsername("이름");
member.setAge(2);
엔티티 매니저의 persist 메서드에 엔티티를 전달하여 INSERT
//엔티티를 등록(CREATE - INSERT)
//inser into member(id, name, age) values(id1, 이름, 2)
em.persist(member);
기존 엔티티를 수정(UPDATE)하려는 경우
수정하고자 하는 엔티티 객체의 Setter 메서드를 통해 값을 변경
//UPDATE MEMBER SET AGE = 20, NAME = "이름" WHERE ID = 'ID1'
member.setAge(20);
테이블을 조회(READ)하려는 경우
조회한 테이블을 담을 동일 엔티티 타입의 참조변수를 선언
엔티티 매니저의 find 메서드에 조회하고자 하는 테이블과 검색조건을 매개변수로 전달
참조변수를 통해 해당 엔티티의 Getter를 통해 값을 조회
//조회(메서드 사용)(READ)
//select name, age from member
Member findMember = em.find(Member.class, "id1");
System.out.println("findMember=" + findMember.getUsername() + ", age=" + findMember.getAge());
createQuery 메서드를 통해 쿼리문을 사용하여 조회 할 수도 있으며,
getResultList 메서드로 리스트 타입으로 변환 가능
리스트에는 조회한 엔티티의 주소값이 담겨 있으므로 주소값을 통해 Getter, Setter 사용가능
//조회(쿼리 사용)(READ)
//SELECT * FROM MEMBER WHERE ID = 'ID1'
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
System.out.println("members.size=" + members.size());
System.out.println(members.get(0).getUsername());
엔티티를 삭제하려는 경우
엔티티 매니저의 remove 메서드에 삭제하고자 하는 엔티티 객체를 전달
//DELETE FROM MEMBER WHERE ID = 'ID1'
em.remove(member);
객체지향 쿼리 언어 JPQL을 통해 조회하는 경우
JPQL은 엔티티 객체를 대상으로 쿼리를 수행
TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
List<Member> memberList = query.getResultList();
TypedQuery 타입 참조 변수를 선언 후에
createQuery 메서드의 매개변수로 수행할 쿼리문과 반환타입을 전달하고
사용하기 편하게 getResultList 메서드를 통해 List에 담고
마찬가지로 주소값을 통해 Getter, Setter를 사용한다.
5. 종료
사용이 끝난 엔티티 매니저와 팩토리는 반드시 종료해야 함
em.close();
emf.close();
'Back-End > JPA' 카테고리의 다른 글
엔티티 매핑 : 학습을 위한 스키마 자동 생성하기 (0) | 2023.06.19 |
---|---|
엔티티 매핑 : 매핑 어노테이션 (0) | 2023.06.19 |
영속성과 엔티티 (0) | 2023.06.01 |
엔티티 매핑 기본 (0) | 2023.05.31 |
JPA (0) | 2023.05.31 |