JPA(Java Persistent API)
JPA에 대해서는 이름만 들어보다가 이번에 학회에서 같이 스터디를 하게 되어 공부를 시작했다.
JPA는 Java진영의 표준 ORM(Object-Relational-Mapping)기술로써, 별도의 쿼리 및 테이블 설계 없이
오직 자바 코드로만 RDB를 자유자재로 이용할 수 있게 해주는 기술이다.
근데 ORM이 뭐지?
ORM(Object-Relational-Mapping)
이름에서 알 수 있듯이, Object와 Relational을 Mapping 해주는 기술이다.
여기서 Object란 OOP(Java, C#, Python) 언어이고 Relational은 RDB(MySQL, Postgresql, MariaDB)등을 말한다.
즉, RDB의 기본 쿼리와 테이블 설계를 우리에게 친숙한 OOP 언어의 객체와 Mapping해준다는 것이다.
ORM을 사용하지 않는다면?
먼저 ORM을 사용하지 않고 회원정보 관리시스템을 개발한다고 생각해보자.
NoSQL이 아닌 RDB를 사용한다고 가정하고, 먼저 정보를 저장할 테이블을 설계 해야 할 것이다.
ID | 이름 | 나이 | 키 |
1234 | 홍길동 | 25 | 177 |
그 다음은 회원 정보를 Client로부터 받아와 DB에 꽂아주는 서비스를 만들기 위해, 최대한 설계한 테이블과 비슷하게
객체를 설계하게 될것이다.
class Member {
public int id;
public String name;
public int age;
public int height;
}
그리고 기본 CRUD 기능을 구현하기 위한 메소드들을 만들고, 실제 DB에 꽂아주기 위해
Query를 일일이 작성해주어야 한다.
public void createMember(Member member){
db.pushQuery("INSERT INTO MEMBER(id, ...)");
}
이때,
- DB마다 Query문법이 살짝살짝 달라서 DB가 바뀌게 되면 전체 코드가 다 바뀌어야 한다.
- Table 설계가 수정이 되게 되면 마찬가지로 전체 코드가 다 바뀌어야 한다.
- 직관적이지 않음
이러한 문제가 존재하게 된다.
또한 Service와 Repository 영역이 강하게 결합되어 계층(Layer) 분할이 이루어지지 않은 코드가 되어버린다.
ORM을 사용하게 된다면?
더 이상 Member 정보를 조합하여 DB에 Query를 날리는것이 아닌, 그냥 객체 그 자체를 DB에 저장하게 된다
public void createMember(Member member){
db.push(member);
}
이렇게 하면 ORM을 지원해주는 프레임워크가 알아서 객체 정보와 테이블 정보를 중간에서 Mapping 해주게 된다.
간단해졌다! 유지보수도 쉽고 가독성도 완전 나아졌다
물론 이렇게 간단하게 되는건 아니고 여러 가지 설정해줘야할 것들이 있긴 하지만 대략적인 개념은 이렇다.
실무에서 가장 중요한것은 데이터이다보니 데이터에 의존적인 개발을 할 수 밖에 없었는데
이를 좀 더 효율적으로 할 수 있는 방법은 없을까? 해서 나온 개념이 JPA이다.
Java 이외에도 다른 언어에도 ORM 기술들이 있다.
C#에는 Entity Framework라고 있는데 그딴 언어는 아무도 안쓰니 JPA가 짱
JPA의 특징
우선 편리해지긴 편리해졌는데, 그 다음으로 자연스럽게 의문이 드는건
성능면에서 괜찮을까? 이다
JPA 진영이 밝힌 성능 최적화 요인은 다음과 같다
- 1차 캐시와 동일성 보장
- 같은 트랜잭션 안에서는 같은 Entity를 반환한다
- ORM을 사용하지 않으면 조회할때 마다 new를 통해 반환해주다 보니 다른 Entity였음
- 일종의 캐시처럼 동작
- 트랜잭션 단위로 이루어지는 Lazy Write
- 트랜잭션이 commit 되기 전까지 실제 Query를 날리지 않음
- Lazy Loading
- 객체가 실제 사용될때 로딩하는 방법으로 사용하지 않으면 Join Query를 날리지 않음
JPA의 모든 데이터 변경은 트랜잭션 안에서만 실행되게 해서 최적화 한다고 한다.
또, JPA는 말 그대로 API로써, 인터페이스이다.
JPA를 구현하는 여러 구현체들이 있으며 대표적으로 Hibernate가 있다.
프로젝트 중간에 DB를 아예 바꾸어도 괜찮은데, 이를 위해 JPA에는 Dialect라고 존재한다.
Dialect는 DB마다 살짝씩 다른 Query들을 JPA가 알아서 Mapping 해주기 위해 현재 DB가 무엇인지
식별하기 위한 프로퍼티이다.
JPQL이란것도 있는데 이는 Java 객체를 쿼리 형식으로 select 할 수 있게 해주는 라이브러리이다.
비슷하게 C#에는 LinQ라고 있는데 이게 더 편해보인다
JPA 구동 방식
- Entitiy Manager Factory
- 애플리케이션당 하나만 생성해서 전체가 공유해야 한다
- Entity Manager
- 트랜잭션 단위당 생성하고 폐기한다
- 서로 다른 쓰레드에서 공유하면 안된다
@Entity
class Member {
@Id public int id;
public String name;
public int age;
public int height;
}
JPA에게 관리를 맡길 객체는 Entity Annotation을, Id 필드는 Id Annotation을 붙여주어야 JPA에서 인식하게 된다.
출처 : https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런
www.inflearn.com
'Back-End > JPA' 카테고리의 다른 글
[JPA] 6. 프록시와 Cascade 및 고아 객체 (0) | 2022.08.04 |
---|---|
[JPA] 5. 상속관계 Mapping & Mapped Superclass (0) | 2022.08.03 |
[JPA] 4. Entity간의 연관관계 Mapping (0) | 2022.07.30 |
[JPA] 3. Entity Mapping (0) | 2022.07.21 |
[JPA] 2. Persistent에 대한 이해 (0) | 2022.07.20 |