일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이펙티브 자바
- java
- 문자열
- 위상정렬
- 파이썬
- JPA
- 스프링
- 헥사고날 아키텍처
- spring security
- 비트마스크
- dataframe
- 포트앤어댑터 아키텍처
- series
- Redis
- dfs
- UML
- equals
- springboot
- DP
- docker
- 다익스트라
- pandas
- disjoint set
- 백준
- BFS
- ddd
- 알고리즘
- 세그먼트 트리
- 자바
- 데이터 flow
- Today
- Total
코딩못하는사람
JPA란? 본문
JPA란?
Java Persistence API 의 줄임말로 자바 진영 ORM 기술의 표준이다.
ORM 이란?
Object-relational mapping(객체 관계 매핑)으로 객체는 객체대로 설계하고 RDB는 RDB로 설계를 한 후 ORM 프레임워크가 중간에서 DB과 객체를 매핑해준다. 객체 지향적으로 설계할 수 있다는 장점이 생긴다.
JPA는 java 애플리케이션과 JDBC사이에서 동작한다. 직접 JDBC를 컨트롤하는 것이 아닌 JPA가 JDBC API를 사용해 SQL 을 호출해서 DB와 동작한다. (JPA가 JDBC를 나 대신 sql을 작성해준다)
JPA는 인터페이스의 모음이다.
구현체로 하이버네이트, EclipseLink, DataNucleus를 가지고 있고 8~90%가 하이버네이트이다.
왜 JPA를 써야할까?
1.생산성
JPA의 CRUD는 간단하다.
- 저장-em.persist(object)
- 조회-em.find(objectId)
- 수정-object.setName("변경할 내용")
- 삭제-em.remove(object)
JPA는 DB를 자바 컬렉션에서 사용하는 것 처럼 하기 위해 만들었다.
수정API를 보면 setName으로 이름을 바꿔주면 변경감지(dirty checking)를 통해 자동으로 update 쿼리가 나가고 DB에 반영된다.
2.유지보수성
새로운 칼럼이 생기면 짜여있던 모든 SQL을 수정해야 하고 오류가 생길 가능성이 큰데
JPA를 사용하면 필드만 추가하면 SQL은 알아서 JPA가 짜준다.
3.RDB,객체의 패러다임 불일치 해결
1.상속
앨범 객체를 저장하고 싶다고 가정해보자. ALBUM 테이블에 INSERT 쿼리를 날리고 ITEM테이블에도 INSERT쿼리를 각각 날려주어야 한다. 하지만 JPA를 사용하게 되면 jpa.persist(album); 한줄로 JPA는 알아서 INSERT 쿼리를 ALBUM,ITEM에 각각 날려준다.
2.조회
위 사진에서 Movie를 찾고싶다고 가정하면 알아서 MOVIE 와 ITEM을 JOIN해서 데이터를 가져와야 한다.
클래스명과 PK로 jpa.find(Movie.class,movieId) 를 해주면 알아서 JOIN쿼리를 짜서 가져와 준다.
ALBUM을 조회했으면 JPA는 ALBUM과 ITEM을 JOIN하는 쿼리를 짤 것이다.
3.연관관계, 객체 그래프 탐색
기존에는 만들어낸 SQL에 따라 탐색 범위가 결정되었다. 따라서 SQL에서 가져오지 않은 객체는 null값으로 탐색이 불가능했다. 하지만 JPA를 사용하면 객체 그래프 탐색이 자유롭다.
예를 들어 연관관계를 다음과 같이 저장했다고 가정하자.
member.setTeam(team);
jpa.persist(member); 으로 연관관계를 설정해주게 된다면 기존 방식에서는
객체가 Team정보까지 가져왔는지 알 수 없다.
하지만 JPA는 바로 컬렉션처럼 member.getTeam()으로 Team정보를 알아낼 수 있다.
기존 JPA를 사용하지 않고 객체를 가져올 때는 메서드가 무슨 쿼리를 만들어내는지 직접 확인해야 하므로
엔티티에 대한 신뢰 문제가 있었다. 하지만 JPA를 사용해서 객체를 가져오면 신뢰 문제가 해결된다.
4.비교하기
기존 SQL 쿼리방식은 같은 식별 값을 가지고 객체를 두번 조회하면 그 값들은 쿼리로 받아온 값을 통해 new 객체를 만들어 반환하므로 서로 ==비교가 다르다고 나왔다.
하지만 JPA는 동일한 트랜잭션에서 같은 식별자로 조회하면 엔티티의 같음을 보장한다.
4.성능향상
JPA라는 연결층을 사용하므로 버퍼링과 캐시기능을 사용해서 성능을 향상시킬 수 있다.
1차 캐시와 동일성 보장
1차캐시 장소를 만들어서 한번 조회했던 엔티티는 캐쉬에서 찾아서 반환해 준다.(큰 성능향상은 어렵다)
다음과 같이 두번 조회하면 첫번째만 SQL이 실행된다
em.find(Member.class,memberId) --SQL
em.find(Member.class,memberId) --캐시
쓰기지연
트랜잭션 커밋 시점까지 INSERT SQL을 모은다.
memberA,B,C를 저장할때마다 네트워크를 타지 않고 한번에 저장한다.
지연로딩과 즉시로딩(LAZY,EAGER)
지연 로딩: 객체가 실제 사용될 때 로딩
즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회
지연로딩은 네트워크를 2번타지만 즉시로딩은 한번에 다 받아온다.
내가 Member와 Team을 항상 같이쓰면 즉시로딩이 유리하겠고 가끔쓴다면 지연로딩이 유리할 것이다.
연관관계 매핑시 fetch 값 설정으로 옵션을 정할 수 있다. fetch =FetchType.LAZY,EAGER은 default
출처- 김영한님 자바 ORM 표준 JPA 프로그래밍 - 기본편를 보고 공부한 자료입니다.
'JPA' 카테고리의 다른 글
JPA 동시성 문제 (0) | 2021.12.31 |
---|---|
Spring Data JPA(1) (0) | 2021.06.05 |