Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
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
Tags more
Archives
Today
Total
관리 메뉴

ultra_dev

JPA 기본 본문

SPRING&JAVA

JPA 기본

ultra_dev 2023. 4. 6. 19:36

기존 방식 

객체를 관계형 DB에 관리한다는 것 이 문제

→ 개발자가 객체로 데이터를 가공했지만 DB에 저장할 땐 결국 SQL → SQL 중심적인 개발이 되버린다.

❓ 무엇이 문제인가?

  1. 기능하나 추가해서 테이블이 생성 될 때마다 CRUD SQL을 다 만들어줘야 한다.

    기존 회원객체와 테이블 기능쿼리 구현
/*회원 객체*/
public class Member {
	private String memberId;
	private String name;
}
/*쿼리*/
INSERT INTO MEMBER(MEMBER_ID, NAME) VALUES ...
SELECT MEMBER_ID, NAME FROM MEMBER M
UPDATE MEMBER SET ...

 

       기획자가 전화번호 필드를 추가 해 달라고 한 상황

/*회원 객체*/
public class Member {
	private String memberId;
	private String name;
	private String tel;
}
/*쿼리*/
INSERT INTO MEMBER(MEMBER_ID, NAME, TEL) VALUES ...
SELECT MEMBER_ID, NAME, TEL FROM MEMBER M
UPDATE MEMBER SET ...TEL = ?

  • 모든 CRUD 쿼리에 TEL을 하나하나 추가해줘야 한다.

결론: SQL에 의존적인 개발을 할 수밖에 없다.



  • 객체를 SQL로 변환해서 RDB에 저장하는 변환과정을 개발자가 해야 한다.
  • → 노가다 시작

이런 문제를 해결하기 위해 나온 것이 JPA

 

자바 ORM 진영의 표준.

 

객체와 테이블을 매핑해서 패러다임의 불일치를 개발자 대신 해결해준다.

 

  • JPA를 자바 컬렉션에 객체를 저장하듯 JPA에게 저장할 객체를 전달.
  • INSERT SQL을 작성하고 JDBC API 사용하는 지루하고 반복적인 일을 JPA가 대신 처리해준다.
  • CREATE TABLE같은 DDL문 자동 생성
  • 데이터베이스 설계 중심의 패러다임을 객체 설계 중심으로 역전
    • 상속, 연관관계, 객체 그래프 탐색, 비교하기 같은 패러다임 불일치 해결

+ JPA는 특정 데이터베이스에 종속되지 않는다

  • ex) 가변문자: mysql은 varchar, oracle은 varchar2
  • ex) 문자열 가르는 함수 : sql 표준은 substring(), oracle은 substr()
  • ex) 페이징 : mysql은 limit, oracle은 rownum
  • 이런 방언(sql 표준 지키지 않는 특정 데이터베이스만의 고유기능)에 종속되지 않음

 


영속성 컨텍스트란?

 

  • 엔티티를 영구 저장하는 환경
  • EntityManager.persist(entity); → 좀 더 풀어서 설명하면 DB에 저장한다기보다는 영속성 컨텍스트를 통해 엔티티를 영속화 한다는 의미
  • 영속성 컨텍스트에 엔티티를 저장한다는 말
  • 영속성 컨텍스트는 논리적인 개념.
  • 눈에 보이지 않는다.
  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
  • 비영속(new/ transient)
  • → 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속(managed)
  • → 영속성 컨텍스트에 관리되는 상태
  • 준영속(detached)
  • → 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제(removed)
  • → 삭제된 상태
  • EntityManagerFactory는 애플리케이션 로딩 시점에 딱 1개만 만듦 → 웹서버 올라오는 시점에 db당 1개만 생성!
  • EntityManager : 실제 db에 저장하는 트랜잭션 단위!! 디비 커넥션 얻어서 쿼리 날리고 종료되는 한 일관적인 단위할 때마다 EntitiyManager 만들어줘야함 🐥 → 고객 요청올 때마다 만들어진다고 보면 됨
  • 엔티티매니저는 쓰레드간에 공유 X!!!!! (사용하고 바로 버려야됨) 만들고 버리고 만들고 버리고~ 데이터베이스 커넥션 빨리 쓰고 돌려주는 것마냥

 

 

 


 

  • 지연로딩: 객체가 사용될 때 로딩
Member member = memberDAO.find(memberId);   //SELECT * FROM MEMBER
Team team = member.getTeam();
String teamName = team.getName(); //SELECT * FROM TEAM
  • 즉시로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회
Member member = memberDAO.find(memberId); // SELECT M.*, T.* F FROM MEMBER JOIN TEAM...
Team team = member.getTeam();
String teamName = team.getName();

 

  • jpa 작동 순서
    1. jpa 트랜잭션 커밋 호출 ( commit() 메소드)
    2. jpa 엔티티 매니저 내부에서 플러시**(flush()**) 발생. 이때 변경된 엔티티들이 쓰기 지연 저장소로 이동
    3. jpa는 플러시 이후 더티 체킹 수행. 변경된 엔티티들과 영속성 컨텍스트에 저장된 원본 엔티티 비교하여 변경 사항 감지
    4. 변경된 엔티티들의 변경 사항을 쓰기 지연 저장소에 모음
    5. 쓰기 지연 저장소에 있는 쿼리들이 데이터베이스에 일괄적으로 보내짐
    6. 트랜잭션 커밋**(commit)** 완료되면 쓰기 지연 저장소에 보관된 변경 사항들이 한번에 데이터 베이스에 반영됨
    7. 롤백시 쓰기지연저장소에 보관된 변경사항들도 롤백됨
    • 조심 : 데이터베이스에 보내는거랑 반영이랑은 다름!! 보내고 커밋완료돼야 반영되는 것!!
Comments