1. 엔티티 매핑
- JPA에서는 엔티티와 테이블을 매핑해서 사용하며, 이러한 매핑을 어노테이션을 통해 쉽게 처리 가능하다.
- 객체와 테이블의 매핑 : @Entity, @Table
- 필드와 컬럼 매핑 : @Column
- 기본 키 매핑 : @Id
- 연관관계 매핑 : @ManyToOne, @JoinColumn
1) @Entity
- @Entity가 붙은 클래스는 JPA가 관리하며 엔티티라고 부른다.
- JPA를 사용해서 테이블과 매핑할 때 클래스는 @Entity 어노테이션이 필수이다.
- 주의사항
- 기본 생성자를 필수로 만들어야 한다. (파라미터가 없는 public 또는 protected 생성자)
- final 클래스, enum, interface, inner 클래스를 사용하면 안된다.
- 저장할 필드에 final를 사용해서는 안된다.
- 속성
- name : JPA에서 사용할 엔티티 이름을 지정한다. 기본값으로 클래스 이름 그대로를 사용하며 같은 클래스 이름이 없으며 가급적 기본값을 사용한다.
2) @Table
- @Table은 엔티티와 매핑할 테이블을 지정한다.
속성 | 기능 | 기본값 |
name | 매핑할 테이블 이름 | 엔티티 이름을 사용 |
catalog | 데이터베이스 catalog 매핑 | |
schema | 데이터베이스 schema 매핑 | |
uniqueConstraints(DDL) | DDL 생성 시에 유니크 제약 조건 생성 |
2. 데이터 베이스 스키마 자동 생성
- JPA는 애플리케이션 실행 시점에 DB 테이블을 생성하는 기능을 제공한다.
- 테이블 중심에서 객체중심으로 데이터를 다룰 수 있도록 한다.
- 데이터베이스 방언(여러 DBMS)을 활용해 데이터베이스에 맞는 적절한 DDL을 생성해준다.
- 이렇게 생성된 DDL은 개발장비에서만 사용이 되며 운영 서버에서는 사용되지 않는다. 필요한 경우에는 적절히 다듬은 후에 사용할 수 있다.
1) 속성
- create : 기존 테이블을 삭제 후에 다시 생성한다. (DROP TABLE + CREATE TABLE)
- create-drop : create와 같으나 종료시점에 테이블을 drop 하며 보통 테스트를 할 때 사용한다.
- update : 변경분만 반영이 된다.(운영 DB에서는 사용하면 안된다.)
- validate : 엔티티와 테이블이 정상 매핑되었는지만을 확인한다.
- none : 사용하지 않는다.
2) 주의점
- 운영 장비에서는 절대 create, create-drop, update를 사용하면 안된다.
- 개발 초기 단계에서는 create 또는 updat를 권장한다.
- 테스트 서버는 update 또는 validate를 권장하며, create하면 데이터가 다 날라간다.
- 스테이징과 운영 서버에서는 validate 또는 none을 사용해야 한다.
- 테스트 서버나 개발 서버에도 본인이 직접 스크립트를 작성하여 문제 없으면 적용해보이는 것이 좋다.
- 로컬 PC에서만 자유롭게 하고 여러 명이 사용하는 개발 서버나 운영 서버에서는 가급적 사용하지 않는다. 그래서 자동으로 생성되는 것을 참고해서 좀 다듬어서 사용하는 것이 더 좋다.
3) DDL 생성 기능
- DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA 실행 로직에서는 영향을 주지 않는다.
// 제약 조건 추가 : 만약 회원 이름이 필수이고 10자를 초과해서는 안되는 경우 @Column(nullable = false, length = 10) // 유니크 제약조건을 추가 @Table(uniqueConstrints = {@UniqueConstraint(name = "NAME_AGE_UNIQUE", columnNames = {"Name", "AGES"} ) }) |
3. 필드와 컬럼 매핑 : @Column
- @Column -> 컬럼 매핑
- name : 필드와 매핑할 테이블의 컬럼 이름, 데이터베이스의 컬럼명을 설정한다.
- insertable, updatable : 등록, 변경의 가능 여부를 설정한다.
- nullable(DDL) : null 값의 허용 여부를 설정하며 false로 설정하면 DDL 생성할 때 not null 제약 조건이 붙는다.
- length(DDL) : 문자 길이 제약조건으로 String 타입에서만 사용이 가능하다.
- columnDefinition(DDL) : 데이터베이스 컬럼 정보를 직접 줄 수 있으며 쓴 것이 그대로 반영된다.
- @Enumerated -> enum 타입 매핑
- EnumType.ORDINAL : enum 순서를 데이터베이스에 저장
- EnumType.STRING : enum 이름을 데이터 베이스에 저장
- default는 무조건 ORDINAL로 되어 있음
- 무조건 EnumType.STRING을 사용해라! -> enum 타입의 데이터 순서가 바뀔 수도 있으므로 절대로 ORDINAL 을 사용하지 마세요..
- @Temporal -> 날짜 타입 매핑
- LocalDate, LocalDateTime을 사용할 때는 생략이 가능하다. (최신 하이버네이트가 지원을 해줌)
- TemporalType.DATE : 날짜, 데이터베이스 data 타입과 매핑(예 : 2013-10-11)
- TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑 (예 : 11:11:11)
- TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑 (예:2013-10-11 11:11:11)
- @Lob -> BLOB, CLOB을 매핑
- 큰 컨텐츠를 넣고 싶을 때 사용
- 매핑하는 필드 타입이 문자면 CLOB을 매핑하며 나머지는 BLOB을 매핑
- @Transient : 특정 필드를 컬럼에 매핑하지 않으며 매핑을 무시
- DB와 관계없이 메모리에서만 사용
- 필드 매핑, 데이터베이스에 저장 및 조회 기능 어떠한 것도 적용되지 않음
4. 기본 키 매핑 : @Id
1) 기본 키 매핑 어노테이션
- 직접 할당 : @Id만 사용
- 자동 생성 : @GeneratedValue
- IDENTITY : 데이터베이스에 위임하며 MYSQL에서 사용
- SEQUENCE : 데이터베이스 시퀀스 오브젝트를 사용하며 ORACLE에서 사용됨. @SequenceGenerator가 필요
- TABLE : 키 생성용 테이블 사용하며 모든 DB에서 사용가능 -> @TableGenerator 필요
- AUTO : 데이터베이스 방언에 따라 자동 지정되며, default값
2) @GeneratedValue(stratege = ) 전략
- default 는 AUTO
- AUTO : DB 방언에 맞춰서 자동으로 생성
- IDENTITY : 기본 키 생성을 데이터베이스에 위임함
- IDENTITY 전략은 DB에 넣어봐야 PK를 알 수 있음
- 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용하며 MySQL에서는 AUTO_INCREMENT
- 하지만 영속성 컨텍스트 1차 캐시에 PK 값이 저장되어 있어야 함
- 보통 commit하는 시점에 INSERT 쿼리가 날라가지만, IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL을 실행하고 DB에서 식별자를 조회함
- 모아서 commit하는 시점에 INSERT 하는 것이 IDENTITY 전략에서는 불가능하며 이것은 단점이 됨
- SEQUENCE : 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트로 Long 타입을 사용하는 것이 좋음
- SEQUENCE 전략이면 em.persist()하는 시점에 DB 테이블에서 다음 값을 얻어와서 객체에 Id 값을 저장한 뒤에 영속성 컨텍스트에 저장함
- 실제 트랜잭션을 commit 하는 시점에 INSERT 쿼리를 호출함
- TABLE : 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략으로 모든 데이터베이스에서 적용 가능한 장점이 있으나 성능이 좋지 않은 단점이 있음
3) 권장하는 식별자 전략
- 기본 키 제약 조건 : null이 아님, 유일한 값이며, 변하면 안됨
- 비즈니스(Membe 테이블에서 id 같은 컬럼)를 키로 끌고 오는 것은 권장하지 않음
- 비즈니스에 의미가 있는 키(주민등록번호 or 이메일) 같은 경우에는 자연키라고 하며 auto_incresement와 같은 자동적으로 식별해주는 키를 대리키라고 한다. 여기서 우리는 자연키보다는 대리키를 권장해야 한다. 비즈니스환경은 언젠가는 변하는 것이며 영원하지 않기 때문이다.
- 권장 : Long 형 + 대체키 + 키 생성 전략으로 사용 가능
추가적으로 Entitiy의 getter를 만드는 것은 상관 없지만, setter는 가급적 생성을 막고 setter의 사용을 최소한으로 하도록 새로 변수에 접근하는 메소드를 만드는 것이 좋음
'프로그래밍공부 > JPA' 카테고리의 다른 글
JPA의 영속성 관리 (0) | 2022.07.20 |
---|---|
JPA 시작 (0) | 2022.07.20 |
JPA란 (0) | 2022.07.17 |