[JPA] JPA 개요, JPA 정의, JPA 장점 (자바 ORM 표준 JPA 프로그래밍 1,2장 요약)
JPA 개요
ORM 프레임워크 : 객체와 관계형 데이터베이스를 매핑해준다.
JPA 정의
- EJB에서 하이버네이트를 기반으로 만들어진 새로운 자바 ORM 기술 표준
- 자바 진영의 ORM 기술 표준이다.(object relational mapping)
- 지루하고 반복적인 crud sql을 알아서 처리해주고, 실행 시점에 자동으로 SQL을 만들어서 실행한다.
- 조회 결과를 객체로 매핑하는 작업을 대부분 자동으로 처리해준다.
JPA 장점
- 어플리케이션을 SQL이 아닌 객체 중심으로 개발하다보니 생산성, 유지보수 측면에서 좋다.
- 1️⃣ 유지보수 측면
- JPA를 사용하면, 이러한 과정을 대신 처리해주기 때문에 수정할 코드가 줄어든다.
- SQL을 직접 다루면 엔티티에 필드를 하나만 추가해도 관련된 등록, 수정, 조회 SQL과 결과를 매핑하기 위한 jdbc api 코드를 모두 변경해야 한다.
- 2️⃣ 생산성 측면
- 데이터베이스 설계 중심의 패러다임을 객체 설계중심으로 역전할 수 있다.
- jpa에게 저장할 객체를 전달해주면 되기 때문에 sql, jdbc api를 직접 작성하지 않아도 된다.
- 1️⃣ 유지보수 측면
- 특정 데이터베이스에 종속되지 않는다.(추상화한 데이터 접근 계층을 제공)
- → 코드 수정이 거의 없이 데이터베이스 변경을 쉽게 할 수 있다.
- 패러다임의 불일치 해결
- 상속, 연관관계, 객체 그래프 탐색과 같은 문제를 해결해준다.
- 객체 그래프를 마음껏 탐색할 수 있다.→ 언제 끊어질 지 모르는 객체 그래프를 탐색해야 한다는 불안감 존재
- → 알아보려면 DAO(데이터 접근계층)를 열어서 sql을 확인해야 하는데, 이는 엔티티와 강한 의존관계를 가진다.
- → (비교) SQL을 직접 다루게 되면 처음 실행하는 sql에 따라 객체 그래프를 어디까지 탐색할 수 있는지 정해진다.
JPA 어플리케이션 만들기
1. 객체 매핑 방법
//Member.java
@Entity
@Table(name="MEMBER")
public class Member {
@Id
@Column(name = "ID")
private String id;
@Column(name = "NAME")
private String username;
// 매핑 정보가 없음
private Integer age;
}
@Table, @Entity, @Column은 회원 클래스에 매핑 정보를 표시하는 어노테이션이다.
@Entity
- 이 클래스를 테이블과 매핑한다고 JPA에게 알려준다.
- JPA의 엔티티 : 테이블을 객체로 표현한 자바 클래스
@Table
- 엔티티 클래스에 매핑할 테이블 정보를 알려준다.
- 여기선 Member 엔티티를 MEMBER 테이블에 매핑한다.
@Id
- 엔티티 클래스의 필드를 테이블의 기본키에 매핑한다.
- 식별자 필드라고 한다.
@Column
- 필드를 컬럼에 매핑한다.
- Member 엔티티의 username 필드를 테이블의 NAME 컬럼에 매핑한다.
NONE
- 매핑 정보가 없을때, 필드명을 이용해 컬럼명으로 매핑한다.
2. 어플리케이션 개발
public class JpaMain {
public static void main(String[] args) {
//엔티티 매니저 팩토리 생성
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(); //엔티티 매니저 팩토리 종료
}
}
- 엔티티 매니저 팩토리 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabook");
- JPA를 사용할 수 있게 준비한다.
- 생성비용이 매우 크기 때문에 어플리케이션 전체에서 딱 한번만 생성되어야 한다.
- 엔티티 매니저 생성
EntityManager em = emf.createEntityManager();
- JPA의 기능 대부분은 이 엔티티 매니저에서 제공한다.
- 엔티티를 데이터베이스에 등록/수정/삭제/조회 할 수 있다.
- 데이터베이스 커넥션을 유지하면서 데이터베이스와 통신하기 때문에 스레드간 공유나 재사용이 불가능하다.
- 종료
em.close();
사용이 끝난 엔티티 매니저는 만드시 종료해야 한다.
emf.close(); //엔티티 매니저 팩토리 종료
엔티티 매니저 팩토리도 다음과 같이 종료한다.
- 트랜잭션 관리
try {
tx.begin(); //트랜잭션 시작
logic(em); //비즈니스 로직
tx.commit();//트랜잭션 커밋
} catch (Exception e) {
e.printStackTrace();
tx.rollback(); //트랜잭션 롤백
} finally {
em.close(); //엔티티 매니저 종료
}
- JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다.
- 트랜잭션을 시작하려면 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.
- 트랜잭션 시작 이후 정상적으로 동작하면 트랜잭션을 커밋하고, 예외가 발생하면 롤백한다.
- 비즈니스 로직
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());
//목록 조회
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
System.out.println("members.size=" + members.size());
//삭제
em.remove(member);
}
- 비즈니스 로직 : 프로그램의 핵심 로직, 어떻게 데이터가 생성되고 저장되고 수정되는지를 정의한 것
- 등록, 수정, 삭제, 조회 작업이 엔티티 매니저를 통해서 수행된다.
- ex)em.remove, em.persist, em.createQuery().getResult() …
- 수정
//수정
member.setAge(20);
수정부분은 독특하다. JPA는 어떤 엔티티가 변경되었는지 추정되는 기능을 갖추고 있기 때문에 엔티티의 값만 변경하면 UPDATE SQL을 생성해서 변경시킨다.
- 목록 조회
//목록 조회
List<Member> members = em.createQuery("select m from Member m", Member.class).getResultList();
JPA에서 엔티티 객체를 대상으로 검색하려면, 모든 데이터를 어플리케이션으로 불러와서 엔티티 객체로 변경한 다음 검색해야 하는데, 이는 불가능하다.
필요한 데이터만 불러오려면 결국 SQL을 사용해야 한다. JPA는 JPQL이라는 쿼리 언어로 이를 해결한다.(JPQL은 SQL를 추상화한 언어다.)
- JPQL, SQL 차이점
SQL
: 데이터베이스 테이블을 대상으로 쿼리한다. JPQL
: SQL을 추상화한 언어다. 엔티티 객체를 대상으로 쿼리한다. 데이터베이스 태이블을 모른다.
JPA는 JPQL을 분석해서 적절한 SQL을 만들어 데이터를 조회한다.
중간 회고
2장까지 보면서 느낀점을 적어보겠다!
프로젝트 경험도 어느정도 있고, 구글링을 통해서 새로운 기능들을 구현하는게 익숙해져서 JPA에 대해 많이 안다고 생각했었는데 완전 큰 오산이었다.
매번 실무형, 실전형만을 운운하며 깊게 공부하지도 않은 채 자신감을 가지고 있었는데 갈수록 깊은 내용에 대해 알고싶다는 열망이 생기는 것 같아서 해당 책을 구매하게 됐다.
SpringData JPA를 경험해 본 적은 있지만 JPA를 이용한 예제는 처음 접해봤는데 사실 이 둘의 차이도 잘 몰랐었다..-_- 충격적으로 얕았던 나의 지식에 반성하며..
그래도 ‘깊게 알아보고 싶다’는 생각이 들었고 스스로 찾아봤다는게 뿌듯하다. 이 책을 만나서 기쁘다!! 이 책을 다 읽을때쯤이면 한층 더 깊은 내가 되길 바란다ㅎ.ㅎ
참고
정확한 정보를 전달하고자 최선을 다하지만, 틀린 부분이 있을 수 있습니다!
틀린 부분이 있을 시 지적해주시면 감사히 반영하겠습니다😀