1. EntityManagerFactory 생성
예시 )
EntityManagerFactory emf = Persistence.createEntityManagerFactory(“DB_NAME”);
META/persistence.xml에서 이름이 “DB_NAME”인 영속성(persistence) 유닛을 찾아서 엔티티 매니저 팩토리를 실행한다.
이때, persistence.xml의 설정정보를 읽어서 JPA를 동작시키기 위한 기반 객체를 만들고,
JPA 구현체에 따라서는 데이터베이스 커넥션 풀도 생성한다.
엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야한다.
[참고] spring에서는 LocalContainerEntityManagerFactoryBean 을 이용
@Primary
@Bean(name = NAME_DATASOURCE)
@DependsOn({NAME_MASTER_DATASOURCE, NAME_SLAVE_DATASOURCE, NAME_ROUTING_DATASOURCE})
public DataSource dataSource(@Qualifier(NAME_ROUTING_DATASOURCE) DataSource routingDataSource) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
@Bean(name = NAME_ENTITY_MANAGER_FACTORY)
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier(NAME_DATASOURCE) DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages(PACKAGE_DATASOURCE_ENTITY)
.persistenceUnit(NAME_PERSISTENCE_UNIT)
.build();
}
2. EntityManager 생성
예시 )
EntityManager em = emf.createEntityMnanger();
엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
따라서 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드간에 공유하거나 재사용하면 안된다.
3. 종료
예시 )
em.close(); // 엔티티 매니저 종료
emf.close(); // 엔티티 매니저 팩토리 종료
마지막으로 사용이 끝난 엔티티 매니저는 다음처럼 반드시 종료해야한다.
애플리케이션을 종료할때는 엔티티 매니저 팩토리도 종료해야한다.
4. 트랜잭션 관리
1 ~ 3번의 내용을 종합하여 작성한 후 트랜잭션을 적용하면, 아래와 같이 표기할 수 있다.
예시 )
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook"); //엔티티 매니저 팩토리 생성
EntityManager em = emf.createEntityManager(); //엔티티 매니저 생성
EntityTransaction tx = em.getTransaction(); //트랜잭션 기능 획득
try {
tx.begin(); //트랜잭션 시작
logic(em); //비즈니스 로직
tx.commit();//트랜잭션 커밋
} catch (Exception e) {
e.printStackTrace();
tx.rollback(); //트랜잭션 롤백
} finally {
em.close(); //엔티티 매니저 종료
}
emf.close(); //엔티티 매니저 팩토리 종료
JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야한다.
트랜잭션 없이 데이터를 변경하면 예외가 발생한다.
[참고] spring에서는 PlatformTransactionManager 을 이용
@Bean
public PlatformTransactionManager transactionManager(
@Qualifier(NAME_ENTITY_MANAGER_FACTORY) EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
5. 비즈니스 로직
예시 )
public void logic(EntityManager em) {
String id = "id1";
Member member = new Member();
member.setId(id);
member.setUsername("지한");
member.setAge(2);
//등록
em.persist(member);
//수정
member.setAge(20);
//한 건 조회
Member findMember = em.find(Member.class, id);
System.out.println("findMember=" + findMember.getUsername() + ", age=" + findMember.getAge());
//목록 조회
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
System.out.println("members.size=" + members.size());
//삭제
em.remove(member);
}
엔티티를 생성한 다음 엔티티 매니저를 통해 데이터베이스에 등록/수정/삭제/조회를 하면된다.
여기서 신기한건 목록 조회 부분인다.
JPA는 엔티티 객체를 중심으로 개발하므로 검색을 할때도 엔티티 객체를 대상으로 검색한다.
그러면 데이터베이스의 모든 데이터를 애플리케이션으로 불러와서 엔티티 객체로 변경한 다음 검색해야하는 데,
이는 현실적으로 불가능하다.
따라서 애플리케이션이 피룡한 데이터만 데이터베이스에서 불러오려면 결국 검색 조건이 포함된 SQL을 사용해야한다.
JPA는 JPQL이라는 쿼리 언어로 이런 문제를 해결한다.
- JPQL : 엔티티 객체를 대상으로 쿼리, 대소문자 구분함
- SQL : 데이터베이스 테이블을 대상으로 쿼리, 대소문자 구분하지 않음
예시에 본 것처럼 select m from Member m 이 부분이 바로 JPQL 인데,
여기서 from Member은 회원 엔티티 객체를 말하는 것으로,
JPQL은 데이터베이스 테이블을 전혀 알지 못하는 점을 잊지말자 !
'Database > JPA' 카테고리의 다른 글
[JPA] 영속성 관리 : 매핑한 엔티티를 엔티티 매니저를 통해 엔티티의 생명 주기는 어떻게 사용되는가 (0) | 2020.08.10 |
---|---|
[JPA] 테이블과 매핑할 클래스 어노테이션 (0) | 2020.08.10 |
[JPA] 버전별 특징 (0) | 2020.08.10 |
[JPA] 데이터베이스 방언, Dialet (0) | 2020.08.10 |
[JPA] 객체와 테이블의 전격 비교 분석 (0) | 2020.08.10 |
[JPA] 그것은 무엇인가? (0) | 2020.08.06 |