티스토리 뷰
JPA와 DB의 맵핑을 알아보기 전에 우선 application의 설정에 대해서 알아볼 필요가 있다.
spring: jpa: hibernate: ddl-auto: none
다음 설정에 대해서 운영환경에서 많은 영향을 미치기 때문이다.
DDL이란 데이터베이스 스키마를 자동 생성하는 설정이다. 따라서 DB는 운영환경에서 매우 중요하기 때문에
해당 설정도 매우 중요하다고 할 수 있다.
운영장비에서는 절대 create, create-drop, update를 사용하면 안된다.
왜냐하면 해당 DB의 정보들이 모두 날아갈 위험이 있기 때문이다.
개발초기에는 create, update
테스트 서버에는 update, validate
스테이징 운영단계에 있는 서버는 validate, none을 사용하는 것이 좋다.
필자는 현재 data ETL 서버를 운영하며 validate 설정을 하고 있다.
앞선 영속성 컨텍스트에서 있던 Member 클래스를 자세히 보자
@Entity @Data public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; @Column(name = "name", insertable = false, updatable = false, nullable = false, unique = true, columnDefinition = "varchar(100) default 'EMPTY'") // 런타임에 영향을 주지 않는다. private String username; private Integer age; @Enumerated(EnumType.STRING) private RoleType roleType; @Temporal(TemporalType.TIMESTAMP) private Date createdDate; @Temporal(TemporalType.TIMESTAMP) private Date lastModifiedDate; @Transient private int temp; }
우선 @Id의 경우에는 현재 이 Entity의 key값으로 정할 멤버 변수이다.
DB의 pk라고 생각하면 편하지만 영속성 컨텍스트의 key값이다.
@Column
- name: DB의 컬럼 명
- insertable: DB에 insert 쿼리를 넣을 수 있는지
- updatable: DB에 update 쿼리를 넣을 수 있는지
- nullable: null을 넣을 수 있는지
- unique: unique 제약조건, 잘 쓰이지 않는다.
- columnDefinition: 직접 조건을 써줄 수 있다.
@Column은 자바의 런타임에 영향을 크게 미치지 않는다.
@Enumerated
이 설정의 경우에는 EnumType.STRING을 쓰는 것을 추천 강제 한다.
왜냐하면 ORDINAL 설정의 경우에는 숫자로 들어가기 때문에 나중에 Enum의 숫자가 변경되거나 다른 변수의 추가시 별도의 작업이 필요하기 때문이다.
@Temporal
날짜 타입에 붙혀주는 애너테이션이다. 현재는 필요가 없어진 옵션이라고 볼 수 있다.
왜냐하면 Java8의 경우에는 LocalDate, LocalDateTime을 자료형으로 하면 자동으로 DB와 매핑되기 때문이다.
@Transient
DB와 맵핑을 하지 않고 싶은 멤버 변수이다.
@GeneratedValue
해당 옵션은 id를 어떠한 자동으로 생성해주는 옵션이다. 설정에 따라서 많은 전략이 있다.
identity
해당 옵션은 DB에게 id 생성을 맡기는 옵션이다.
em.persist를 호출하는 시점에서 select 쿼리가 날아간다. 왜냐하면 DB에서 pk값을 받아와야 하기 때문이다.
sequence
oracle DB에서 많이 사용되는 옵션이다.
DB의 sequence에서 값을 가져온 뒤에 저장을 해주는 옵션이다.(sequence는 DB에 있는 개념이다.)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator") @GeneratedValue(strategy = GenerationType.IDENTITY)
sequence 옵션을 쓸때에는 generator를 별도로 설정을 해주어야 한다.
왜냐하면 DB에 있는 sequence를 매칭해야하기 때문이다.
@SequenceGenerator( name = "member_seq_generator", sequenceName = "member_seq", initialValue = 1, allocationSize = 1 )
다음처럼 class위에 붙히는 애너테이션이다.
여기서 allocationSize가 중요한 옵션이다. sequence는 우선 nextVal을 통해서 다음 값을 받아오는데,
allocationSize만큼 한번의 쿼리로 값을 받아와 id를 받아오는 쿼리를 최소화 할 수 있다.
한마디로 DB에서 sequence를 가져온 뒤에 next value 쿼리를 날린 후(영속성 컨텍스트에 저장) allocationSize만큼을 받아오게 된다는 것이다. 한번에 받아온 값에 대해서는 메모리에서 호출을 할 수 있다.
기본키 제약 조건
마지막으로 기본키를 어떻게 생성하면 좋을까에 대한 것이 있다.
자연키(DB의 컬럼중 하나)는 미래까지 조건을 unique하다는 것을 만족하기 힘들다. 이 점에서 @GeneratedValue로 대리키를 사용하는 것이 좋은 전략이라고 볼 수 있다.
따라서 Long + 대체키 + 키 생성전략 사용을 하는 것을 권장한다.
출처
인프런 자바 ORM 표준 JPA 프로그래밍 - 기본편
'Back End > JPA' 카테고리의 다른 글
[JPA 기초] 3-1. @MappedSuperclass (0) | 2022.10.14 |
---|---|
[JPA 기초] 3. 연관관계 맵핑 (0) | 2022.10.14 |
[JPA 기초] 1. 영속성 컨텍스트 (0) | 2022.10.03 |
[API] 5. 1:N 관계 조회 최적화 - 1 (0) | 2022.09.17 |
[API] 4. JPA 조회 성능 최적화(N+1문제와 fetch join) (0) | 2022.09.05 |
- Total
- Today
- Yesterday
- OS
- Data Engineering
- apache
- JPA
- feign client
- K8S
- KAFKA
- 프론트엔드
- Firebase
- spring boot
- NextJS
- apache kafka
- cs
- centos
- API
- logback
- Front
- Producer
- consumer
- spring
- Container
- Java
- React
- docker
- Linux
- zookeeper
- frontend
- broker
- 리액트
- rhel
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |