본문 바로가기

Spring boot

[spring boot] 1차 정리(jpa 시작, 영속성관리, 엔티티 매핑)

준영속 상태

tx.commit(); : 쿼리 날리기. 맨 마지막에 한번만 실행하면 됨.  

detach : 준영속 상태로 만듦

setName으로 name을 변경하고 detach를 하면 setName때문에 select 쿼리는 날라가지만 commit 때 setName으로 인한 update 쿼리는 안 날라감.

detach를 함으로써 영속성 컨텍스트를 날려버린 것. (변경 감지 일어나지 않음)

 

객체와 테이블 매핑

@Table(name = "MBR")

public class Member{

}

는 table명을 MBR로 정한다.

MBR table과 맵핑되어 쿼리가 insert 쿼리 from MBR; 로 날라감.

 

 

데이터베이스 스키마 자동 생성

application 로딩시 DB를 자동으로 생성해 객체중심으로 개발가능.

------------------------

hibernate.hbm2ddl.auto value ="create"설정시 기존테이블 삭제 후 새로 생성 (age 필드 하나 더 생성하면 DB가서도 alter age 컬럼 추가됐다 쿼리 날려야하지만 그럴 필요 x)

=> 개발할 때 필드 하나더 생각나면 DB까지 안 건들이고 바로 고칠 수 있다는 메리트가 있다.

value="update" 필드를 update하는 쿼리인 alter는 가능한데 delete는 불가 

value="validate"는 DB에 없는 필드(gogo2)가 Entity에 있을때 DB와 연결되지 않았다고(DB에 그 필드가 없다) 알려줌.

-------------------------

! 이 기능은 local서버에서만 쓰고 여러명이 쓰는 운영, 개발 서버에서는 스크립트 직접 쓰기..! 

--------------------------

@Table은 테이블명을 바꿈(insert, update쿼리)으로써 runtime에 영향을 줌. 

@Cloumn은 alter쿼리만 추가로 생김 runtime에 영향을 주지 않음.

----unique 조건 : 중복 값 저장x

 

 

필드와 컬럼 매핑

DB에서 enum쓰고 싶으면 @Enumurated

Date사용하고 싶으면 TIMSTAMP 사용

CLOB: String인데 varchar보다 긴거

@Transient : DB에는 안 만들고 메모리에서만 쓰고 싶을 때  

! enum 타입은 ordinal을 사용하면 안된다. enum순서가 바뀌면 옛날 데이터가 새 데이터로 변경되지 않음

 

기본 키 매핑

데이터 개수 10억 아래는 Integer 사용이 좋지만 그 이상이면 나중에 타입 바꾸는게 더 힘듦, so SEQUENCE는 Long 타입 사용해야함. 

권장 : indentity나 sequece object 둘 중 하나 쓰거나 때에 따라 유효 아이디나 랜덤값을 조합한 회사내의 룰을 이용해 PK만들기 

 

identity(데이터베이스에 위임, MYSQL)

identity 전략에서는 ID(PK)값을 DB에 데이터가 들어가봐야 알 수 있음. BUT JPA가 영속성 컨텍스트를 관리하려면 PK값이 무조건 있어야함.

=> 보통 commit();할 때 쿼리가 DB에 날라가지만 identity전략에서는 일단 DB에 데이터를 넣어야 pk값을 알 수 있음. 따라서 persist하자마자 바로 insert쿼리가 DB에 날라감.

jpa는 아래처럼 값 반환받고 바로 그 값들을 셋팅한 후 영속성 컨텍스트의 pk로 씀 

= so. 모아서 쿼리보내는건 불가능 (batch불가)

 

sequence(데이터베이스 시퀀스 오브젝트 사용, ORACLE)

persist(jpa가 데이터를 영속성컨텍스트로 관리)하려면 pk필요  so. DB에서 sequence 들고와야함. call sequence객체 => 영속성 컨텍스트에 entity(ex-member) 저장, 이 때 persist를 한거지 commit은 아님.

sequence 방법이 sequence 객체 값도 불러오고 insert쿼리도 보내니 connection이 2번이나 됨. =낭비 

따라서 allocationSize사용 ex)50이면 DB는 한번 sequence call하면 50으로 저장됨, 그리고 application에서 1부터 50까지 하나씩증가하며 사용하다가 application sequence가 결국 50이 되면 또 DB에 next call 함 => DB는 먼저 100이 저장되고 application에서 51부터 쓰다가 100되면 또 next call (DB에 먼저 50씩 sequence 값 올려놓고 메모리에서 sequence 1개씩 쓰기)

 

sequence 값

sequence 맨 처음 호출(1로 초기화)은 일단 호출하고 어라 난 50개 단위인데 하고 다시 호출로 51로 설정해줌. 첫 호출은 가짜로 된거  

sequence call             (DB: 1)

em.persist(member1);  (DB:51, application : 1)

em.persist(member2);  (DB:51, app(메모리): 2)

em.persist(member3);  (DB:51, application(메모리) : 3)

--------------

allocation 의 동시성 문제는 없다

왜냐하면 웹서버 1개는 1~51까지 쓰고 웹서버2가 next call하면 52~101까지 쓰고 이러니까..! 동시성문제는 없다. 

 

 

실전 예제 1 - 요구사항 분석과 기본 매핑

table명 중 order는 예약어라서  @Table(name="orders")로 바꿔주기.

DB 주소를 "~test"말고 다른걸로 바꿔줘서 아예 다른 DB로 새로 생성