본문 바로가기

Database/JPA

[JPA] 프로젝트에서 JPA 적용 방법

반응형

 

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 데이터베이스 테이블을 전혀 알지 못하는 점을 잊지말자 !

 

반응형

❥ CHATI Github