JPA 1~2장 스터디
by ag-lee
1장_JPA 소개
JPA는 자바 ORM(Object-Relational Mapping) 기술에 대한 API 표준 명세로 가장 널리 쓰이는 것은 하이버네이트이다. 애플리케이션을 객체 중심으로 개발할 수 있도록 도와주어 생산성과 유지보수성을 높여준다.
SQL을 직접 다룰 때 발생하는 문제점
- 엔티티를 신뢰할 수 없다.
- 진정한 의미의 계층 분할이 어렵다.
- SQL에 의존적인 개발을 하게 되어 엔티티 변경에 많은 공수가 들어간다.
JPA를 사용해야 하는 이유
-
생산성
JPA를 사용하면 Java Collection에 저장하듯 객체를 간단하게 저장할 수 있다.
-
유지보수
직접 SQL을 다루면 엔티티에 변경이 있을 때 관련이 있는 SQL문을 모두 변경해주어야 한다. JPA를 사용하는 경우는 이 부분을 JPA가 처리해주기 때문에 수정할 코드가 줄어든다.
-
패러다임의 불일치 해결
객체의 상속, 연관관계, 객체 그래프 탐색 등의 관계형 데이터베이스로 해결할 수 없는 문제를 해결할 수 있다.
-
성능
JPA를 이용해 애플리케이션과 데이터베이스 간의 다양한 성능 최적화를 시도해볼 수 있다.
-
데이터 접근 추상화와 벤더 독립성
애플리케이션과 관계형 데이터베이스 사이의 추상화된 데이터 접근 계층을 제공하므로 애플리케이션이 특정 데이터베이스에 종속되지 않는다.
2장_ JPA 시작
객체 매핑 시작
CREATE TABLE MEMBER (
ID VARCHAR(255) NOT NULL,
NAME VARCHAR(255),
AGE INTEGER,
PRIMARY KEY (ID)
);
@Entity
@Table(name="MEMBER")
public class Member {
@Id
@Column(name = "ID")
private String id;
@Column(name = "NAME")
private String username;
private Integer age;
// getter, setter 생략
}
@Entity
: 이 클래스가 테이블과 매핑되는 entity라는 것을 표시한다.@Table
: 엔티티에 매핑할 테이블 정보를 알려준다. Name 속성이 없는 경우 엔티티 이름을 이용해 매핑한다.@Id
: 필드를 테이블의 primary key와 매핑한다. (식별자 필드)@Column
: 필드를 컬럼과 매핑한다. name에 db 컬럼명을 적어주면 매핑된다. 어노테이션을 생략하면 필드명을 사용해서 컬럼명으로 매핑한다.
persistence.xml
설정
persistence.xml은 JPA의 기본 설정 파일로 resources/META-INF/persistence.xml
경로에 있으면 인식된다.
<persistence-unit name="jpabook">
영속성 유닛 설정. 일반적으로 데이터베이스 당 고유한 이름을 가진 하나의 영속성 유닛을 등록한다.
애플리케이션 개발
1. 엔티티 매니저 생성
//엔티티 매니저 팩토리 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
EntityManager em = emf.createEntityManager(); //엔티티 매니저 생성
// 생략
em.close(); //엔티티 매니저 종료
emf.close(); //엔티티 매니저 팩토리 종료
-
엔티티 매니저 팩토리 생성
먼저, persistence.xml의 정보로
EntityManagerFactory
를 생성한다. 이 코드에서는 이름이 jpabook인 persistence-unit을 찾아 그 정보로 생성해준다. EntityManagerFactory를 생성할때 DB 커넥션 풀을 생성하는 등 비용이 크므로 애플리케이션 전체에서 하나를 생성해 공유한다. -
엔티티 매니저 생성
엔티티 매니저 팩토리에서
EntityManager
를 생성할 수 있다. EntityManager는 데이터 베이스 커넥션을 유지하며 데이터 베이스와 통신한다. 데이터 베이스 커넥션과 밀접한 관계가 있으므로 스레드간 공유하거나 재사용하면 안된다.
2. 트랜잭션 관리
2. 트랜잭션 관리
EntityTransaction tx = em.getTransaction(); //트랜잭션 기능 획득
try {
tx.begin(); //트랜잭션 시작
logic(em); //비즈니스 로직
tx.commit();//트랜잭션 커밋
} catch (Exception e) {
tx.rollback(); //트랜잭션 롤백
}
JPA를 사용할 때 트랜잭선을 만들어 트랜잭션 내에서 데이터를 변경해야한다. 트랜잭션을 만드려면 EntityManager
에서 트랜잭션을 가지고 와야한다.
###3. 비즈니스 로직
public static 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());
//삭제
em.remove(member);
}
등록, 수정, 삭제, 조회 등의 기능은 EntityManager
를 통해 수행된다.
- 등록 : 엔티티 매니저의
persist()
함수에 저장할 엔티티를 넘겨주면 저장된다. - 수정 : JPA는 엔티티 변경에 대해 추적하는 기능을 가지고 있다. 때문에 엔티티의 값을 변경하면 UPDATE 문을 생성해 데이터베이스 값을 변경한다.
- 삭제 :
remove()
메소드에 삭제하려는 엔티티를 넘겨준다. - 한건 조회 :
find()
메소드는 조회할 엔티티와 pk를 넘겨주면 엔티티 하나를 조회한다.
JPQL
//목록 조회
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
System.out.println("members.size=" + members.size());
테이블이 아닌 엔티티 객체를 대상으로 검색하려면 데이터베이스의 모든 데이터를 애플리케이션으로 불러와 엔티티 객체로 변경해 검색해야 하는데 불가능하므로 쿼리를 이용한다.
JPQL
: JPA가 제공하는 쿼리 언어. 엔티티 객체를 대상으로 쿼리한다. 때문에 JPQL은 데이터베이스 테이블을 전혀 알지 못한다.
reference
자바 ORM 표준 JPA 프로그래밍 에이콘 오픈 소스 프로그래밍 시리즈,스프링 데이터 예제 프로젝트로 배우는 전자정부 표준 데이터베이스 프레임워크