[JPA] 엔티티 매핑
- [ Backend ]/Spring DB, JPA
- 2021. 12. 31.
설계적인 측면 (객체와 관계형 데이터베이스를 어떻게 매핑해서 사용하는지)에 관한 공부
객체와 테이블 매핑
- @Entity : JPA가 관리하는 객체 명시
- 클래스와 테이블을 매핑하기 위하여 클래스에 @Entity를 명시해준다. @Entity가 명시되지 않은 클래스는 JPA가 관리대상으로 생각하지 않기 때문에 JPA를 사용해서 테이블과 매핑하려면 @Entity 어노테이션을 반드시 명시해주어야 한다.
- 기본(public/protected) 생성자가 필수적으로 요구된다.
- DB에 저장할 필드에 final 사용이 불가능하다.
- @Table : 엔티티와 매핑할 테이블 지정
- @Table(name = " ")와 같이 매핑할 테이블의 이름을 변경할 수 있다.
데이터베이스 스키마 자동 생성이란?
JPA는 애플리케이션 로딩 시점에 DB테이블을 생성(CREATE)하는 기능도 지원한다. 실무가 아닌 개발환경 구축에는 데이터베이스에 별도로 테이블을 구축해줄 필요가 없으므로 유리하다. persistence.xml파일에서 hibernate,hbm2ddl.auto의 value값을 지정해줌으로서 모드를 바꿀 수 있다.
//기존테이블 삭제 후 다시 생성
<property name="hibernate.hbm2ddl.auto" value="create" />
//create와 같으나 종료시점에 drop(테이블 삭제) - 테이트코드에 사용하기 좋음
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
//변경분만 반영(alter. 다만 변경이라고해서 삭제는 안된다-포맷방지)
<property name="hibernate.hbm2ddl.auto" value="update" />
//엔티티와 테이블이 정상 매핑되었는지만 확인. 매핑되지 않으면 오류발생
<property name="hibernate.hbm2ddl.auto" value="validate" />
//주석처리한것과 동일
<property name="hibernate.hbm2ddl.auto" value="none" />
주의) 특히 실무, 운영서버에서 create, create-drop, update를 사용하면 안된다(validate, none) - 그냥 none으로 두고 사용하자. 로딩 시점에 시스템이 자동으로 작성해주는것이 마냥 좋은 것은 아니다.
@Column(unique=true, length=10)
private String name;
또한 column에 옵션을 추가할 수 있다.
JPA는 생성할때마다 어노테이션을 보고 DDL을 생성하는데 영향을 준다. (DDL을 자동 생성할때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다)
※DDL : CREATE, ALTER와 같이 SCHEMA, TABLE등을 정의하거나 변경할때 사용하는 언어를 지칭
필드와 컬럼 매핑
1. Member객체를 일반 회원과 관리자로 구분하기
2. 회원 가입일과 수정일 정보 추가
3. 회원을 설명할 수 있는 필드 추가
@Entity
public class Member {
@Id
private Long id;
//객체명은 username으로 쓰고싶은데 db에는 name이라고 컬럼 생성하기 위해
@Column(name = "name")
private String username;
//Integer형으로 만들면 자동으로 적합한 정수형으로 변환
private Integer age;
//Enum형을 DB에서 사용할 수 있게 해줌
@Enumerated(EnumType.STRING)
private RoleType roleType;
//DATE(날짜), TIME(시간), TIMESTAMP(날짜,시간) 중에서 설정 가능
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
//큰 정보를 넣게 해줌
@Lob
private String description;
//Getter, Setter…
}
- @Column 속성
-@Enumerated 속성
위 속성의 기본값은 ORDINAL인데 무조건 STRING으로 사용하도록 하자. ORDINAL으로 사용하면 integer로 변환되어 enum에서 지정한 순서가 저장된다. 그런데 enum타입의 순서가 DB연동중에 바뀌면 큰 문제가 발생할 수 있으므로 반드시 STRING으로만 사용하자.
-@Transient 속성
엔티티 객체의 데이터와 테이블의 컬럼과 매핑하고 있는 관계를 끊기 위해 사용한다.
매핑 속성 정리
기본 키 매핑
- @Id
아이디 직접 할당시 사용
- @GeneratedValue
아이디 자동 생성시 사용
<옵션>
@GeneratedValue(strategy = GenerationType.AUTO) : 방언에 따라 밑의 3가지중 자동 지정. 기본값
= GenerationType.IDENTITY) : 키 생성을 데이터베이스에 위임
= GenerationType.SEQUENCE), @SequenceGenerator를 이용하여 테이블마다 시퀀스 관리 : 유일한 값을 순서대로 실행해주는 데이터베이스 오브젝트 사용
= GenerationType.TABLE), @TableGenerator : 키 생성 테이블 사용
식별자 생성 전략 : 식별자는 NULL이 아니고, 유일해야하고, 변하면 안된다. 그런데 애플리케이션이 존재하는, 최대 수십년의 시간 동안 이러한 조건을 만족하는 자연키를 찾는것은 쉽지 않다. 따라서 대리키(대체키-랜덤값, generatedvalue,uuid 등)를 사용하자.
- 저번 포스트에서 언급했었듯, 영속성 컨텍스트에 들어가기 위해서는 무조건 PK값이 있어야 한다. (영속상태가 되기 위해서는 컨텍스트의 1차 캐시에 id값과 Entity정보가 들어가야한다.) 그런데 IDENTITY같은 경우에 DB에 키 생성을 위임하므로 DB에 전달되기 전에는 id정보를 알 수 없다. 그래서 예외적으로 @GeneratedVallue의 strategy가 GenerationType.IDENTITY일 경우에만 em.persist 호출시 커밋하지 않아도 쿼리(INSERT)문을 날리고 db에서 다시 읽어와서 캐시에 넣는 방법을 택한다.
'[ Backend ] > Spring DB, JPA' 카테고리의 다른 글
[JPA] 연관관계 매핑(1) - 객체와 테이블 (0) | 2022.01.04 |
---|---|
[JPA] 기본 키 매핑-SEQUENCE 전략, 에러 해결 (0) | 2022.01.02 |
[JPA] JPA 구조, 특성 (0) | 2021.12.29 |
[JPA] JPQL 예시 (0) | 2021.12.28 |
[JPA] 설정, 기본 실습 (0) | 2021.12.28 |