JPA(Java Persistence API)
JPA는 자바 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용되는 인터페이스의 모음이다.
인터페이스라는 말은?
- 실제적으로 구현된 것 X
- 구현된 클래스와 매핑을 해주기 위해 사용되는 프레임워크
JPA를 구현한 대표적인 오픈소스: Hibernate
JPA는 애플리케이션과 JDBC(Java Database Connectivity) 사이에서 동작한다.
스프링에서 흔히 사용하는 것으로 알고있는 JPA는 JPA를 이용하는 Spring Data JPA 프레임워크이다.
JPARepository란 Spring Data JPA에서 제공하는 인터페이스 중 하나로, JPA를 사용하여 데이터베이스를 조작하기 위한 메서드를 제공한다.
ORM(Object-Relational Mapping)
개념적 정의: 우리가 일반적으로 알고있는 애플리케이션 Class와 RDB의 테이블을 매핑(연결)
기술적 정의: 애플리케이션의 객체를 RDB 테이블에 자동으로 영속화 해주는 것
ORM의 장점
- SQL문이 아닌 Method를 통해 DB를 조작한다.
- 개발자는 객체 모델을 이용하여 비즈니스 로직을 구성하는데만 집중할 수 있다.
- 내부적으로는 쿼리를 생성해서 DB를 조작하지만, 개발자가 쿼리를 생성하지 않아도 된다는 것!!
- 쿼리와 같은 부수적인 코드가 줄어들어, 각종 객체에 대한 코드를 별도로 작성하여 코드의 가독성을 높인다.
- 객체지향적인 코드 작성이 가능하다.
- 매핑하는 정보가 Class로 명시되었기 때문에 유지보수 및 리팩토링에 유리하다.
- DBMS를 바꾸더라도 새로 쿼리를 수정할 필요가 없다.
ORM의 단점
- 프로젝트의 규모가 크고 복잡하여 설계가 잘못된 경우, 속도 저하 및 일관성을 무너뜨리는 문제점이 생길 수 있다.
- 복잡하고 무거운 쿼리는 속도를 위해 별도의 튜닝이 필요하기 때문에, 결국 SQL문을 써야할 수도 있다.
- 학습 비용이 비싸다.
영속성 컨텍스트(Persistence Context)
엔티티를 영구 저장하는 환경이라는 뜻이다.
엔티티 매니저로 엔티티를 저장하거나 조회하면, 엔티티 매니저는 영속성 컨텍스트에서 엔티티를 보관하고 관리한다.
EntityManager.persist(entity);
JPA를 공부하다 보니, persist() 함수를 많이 보게 되어 이 함수의 동작이 궁금하였다.
이 코드는 엔티티 매니저를 사용해서 엔티티를 DB에 저장하는게 아니라 영속성 컨텍스트라는 곳에 저장하게 된다.
영속성 컨텍스트는 엔티티 매니저를 생성할 때 만들어진다.
JPA는 기본적으로 트랜잭션 단위로 영속성 컨텍스트가 부여되어 사용된다.
(트랜잭션을 선언하지 않았는데, Spring Data JPA를 사용한다면, JPARepository 코드 내부에서 트랜잭션을 별도로 사용한다.)
트랜잭션(transaction) : 데이터베이스의 상태를 변화시키기 위해서 수행하는 작업의 단위
- J2SE 환경 : 개발자가 직접 엔티티 매니저를 생성하고 트랜잭션을 관리
- J2EE, 스프링 프레임워크 같은 컨테이너 환경 : 컨테이너가 트랜잭션과 영속성 컨텍스트를 관리
트랜잭션이 같으면 영속성 컨텍스트도 같이 쓰고, 트랜잭션이 다르면 다른 영속성 컨텍스트를 쓰게 된다.
J2EE, 스프링 프레임워크 같은 컨테이너 환경의 장점은 트랜잭션과 복잡한 멀티 쓰레드 상황을 컨테이너가 처리해 준다.
J2SE(Java Standard Edition) : 일반 개발자가 사용하는 자바 표준 배포판
J2EE(Java Enterprise Edition) : 기업용 애플리케이션을 개발하는데 필요한 여러 도구 및 라이브러리를 모은 것
엔티티 생명주기
엔티티에는 4가지 상태가 존재하며, 생명주기는 아래의 그림과 같다.
- 비영속(new/transient): 영속성 컨텍스트와 관계가 없는 상태
- 영속(managed): 영속성 컨텍스트에 저장된 상태
- 준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed): 삭제된 상태
비영속(new/transient)
엔티티 객체를 생성하여 순수한 객체의 상태이며, 저장하지 않은 상태를 말한다.
따라서 영속성 컨텍스트나 데이터베이스와 관련이 없다.
// 객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
영속(managed)
엔티티 매니저를 통해 엔티티를 영속성 컨텍스트에 저장한 상태를 말한다.
영속성 컨텍스트가 관리하는 엔티티를 영속상태라고 한다.
EntityManager.find() 또는 JPQL을 사용해서 조회한 엔티티도 영속성 컨텍스트가 관리하는 영속상태이다.
//저장 : 영속
entityManager.persist(member);
//한 개만 조회 : 영속
entityManager.find("user1");
//목록 조회 : 영속
List<Member> members = entityManager.createQuery("SELECT m FROM Member m", Member.class).gerResultList();
준영속(detached)
영속성 컨텍스트가 관리하던 영속상태의 엔티티를 영속성 컨텍스트가 관리하지 않으면 준영속 상태가 된다.
특정 엔티티를 준영속 상태로 만드려면 아래의 메소드들을 호출하면 된다.
entityManager.detach() //분리
entityManager.close() //영속성 컨텍스트 닫음
entityManager.clear //영속성 컨텍스트 초기화
삭제(removed)
엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다.
entityManager.remove();
틀린 부분이 있으면 지적해주시면 감사하겠습니다.
Reference
영속성 컨텍스트(Persistence Context) #1
'Server' 카테고리의 다른 글
[SpringBoot] Entity 생성하기 / JPA 간단한 예제 (0) | 2024.08.07 |
---|---|
[JPA] cannot drop table '' referenced by a foreign key constraint '' on table 오류 해결 (0) | 2024.08.05 |
[JPA] GenerationType.IDENTITY 오류 / AUTO_INCREMENT (0) | 2024.08.02 |
DDD 개념 / DAO와 Repository 차이 (0) | 2024.07.31 |
[SpringBoot] 패키지 구조 선택하기 계층형/도메인형 (0) | 2024.07.30 |