JPA가 관리하는 Entity로 만들기 위해서는 해당 클래스에 어노테이션을 활용해야함.
- @Entity
- JPA가 관리할 객체라는 것을 명시
- PK 값을 나타내는
@Id
는 반드시 필요- 기본 생성자 필수
final
,enum
,interface
,inner
클래스에는 사용 불가- 필드에
final
키워드 사용 불가
- @Table
- 엔티티와 매핑할 테이블을 지정
name
속성을 사용하여 테이블 이름을 지정@Entity @Table(name = "car") public class Car { // PK @Id private Long id; // 필드 private String maker; private String model; // 기본 생성자 public Tutor() { } public Tutor(Long id, String maker, String model) { this.id = id; this.maker = maker; this.model = model; } }
- @Id
- 엔티티를 생성할 때 필수로 존재해야 하며, 단독으로 사용시 DB에 데이터를 저장할 때 ID값을 수동으로 설정해줘야 함
- 가장 권장되는 방식은
Long
타입의 기본키를 사용하는 것- @GeneratedValue
- ID값을 자동으로 생성해주며,
strategy
속성을 사용하여 다양한 설정 가능
- GenerationType
- IDENTITY : MySQL, PostgreSQL에서 사용하며, PK 자동 생성
- SEQUENCE : Oracle에서 사용하며,
@SequenceGenerator
와 함께 사용- TABLE : 키 생성용 테이블을 사용하며,
@TableGenerator
와 함께 사용- AUTO : DB 종류에 따라 자동 지정하며
GenerationType
의 기본값
엔티티의 필드는 테이블의 컬럼과 매핑되며, 다양한 설정 가능
@Column
생략해도 DB 컬럼으로 매핑이 가능하지만, 다양한 옵션을 사용하기 위해 설정
속성 설명 기본값 name 객체 필드와 매핑할 테이블의 컬럼 이름 설정 객체 필드 이름 nullable DDL 생성 시 null 값의 허용 여부 설정 true(허용) unique DDL 생성 시 유니크 제약 조건 설정 - columnDefinition DDL 생성 시 컬럼 정보 설정 - length DDL 생성 시 문자 길이 설정(String만 가능) 255 insertable 설정된 컬럼의 INSERT 가능 여부 true updatable 설정된 컬럼의 UPDATE 가능 여부 true
- @Temporal
- 날짜 타입을 설정
- 객체 필드의 데이터 타입이
LocalDate
,LocalDateTime
인 경우에는 생략 가능
- @Enumerated
- enum 값을 사용하기 위해 설정(DB에는 enum 타입이 없음)
- 속성으로
value
를 사용하며, 값으로는 enum의 이름을 저장하는EnumType.STRING
을 사용- 값이 추가될 때마다 순서가 변하기 때문에 enum의 순서를 저장하는
EnumType.ORDINAL
은 사용하지 않음
- @Transient
- DB 컬럼과 매핑하지 않을 때 사용
@Entity @Table(name = "board") public class Board { @Id private Long id; // @Column을 사용하지 않아도 DB 컬럼으로 매핑 private Integer view; // 객체 필드 이름과 DB 컬럼 이름을 다르게 설정 가능 @Column(name = "title") private String bigTitle; @Enumerated(EnumType.STRING) private BoardType boardType; // longtext를 설정하면 VARCHAR()를 넘어서는 큰 용량의 문자열 저장 가능 @Column(columnDefinition = "longtext") private String contents; // 날짜 타입 (DATE, TIME, TIMESTAMP) 사용 가능 @Temporal(TemporalType.TIMESTAMP) private Date createdDate; // LocalDate를 사용했기 때문에 @Temporal 생략 가능 private LocalDate lastModifiedDate; // 객체에선 필요하지만 DB에는 필요 없은 필드 @Transient private int count; public Board() { } }
💡 hibearnate.hbm2ddl.auto
애플리케이션 로딩 시점에 JPA가 DDL을 생성하기 위해 필요한 설정 값.
설정값 설명 create 기존 테이블을 삭제(DROP)한 후 다시 생성(CREATE) create-drop 기존 테이블을 삭제(DROP)한 후 다시 생성(CREATE)하고 애플리케이션 종료 시점에 테이블을 삭제(DROP) update 엔티티에서 변경된 사항만 DDL에 반영(데이터 타입, 컬럼명 등) validate 엔티티와 테이블이 정상적으로 매핑 되었는지 확인하며, 실패 시 예외 발생 none 속성을 사용하지 않는 것으로서 아무 변화 없음 // application.properties에서의 사용 예시 hibernate.hbm2ddl.auto=create
객체 간의 관계가 한쪽에서만 참조될 수 있는 관계. 설정이 단순하고 유지 관리가 쉬우며 불필요한 데이터 접근 방지 가능.
- 객체가 다른 객체를 참조
- N:1 관계일 경우,
@ManyToOne
,@JoinColume
을 사용- N에 해당하는 테이블(Tutor)의 외래키와 1에 해당하는 테이블(Company)의 PK를
@JoinColumn
으로 매핑@Entity @Table(name = "tutor") public class Tutor { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // N:1 단방향 연관관계 설정 @ManyToOne @JoinColumn(name = "company_id") private Company company; // 기본 생성자, getter/setter }
객체 간의 관계가 양쪽에서 서로를 참조할 수 있는 관계. 양쪽에서 데이터에 쉽게 접근할 수 있지만, 관계를 관리할 때는 한쪽에서만 연관관계를 설정하거나 삭제하지 않도록 주의 필요.
- DB 관점에서는 연관관계에 방향의 개념이 없음
- 따라서 테이블에 변화는 없음
- 양방향 연관관계 설정을 위해
mappedBy
속성을 설정
- Tutor → Company N:1 연관관계 (단방향)
- Company → Tutor 1:N 연관관계 (단방향)
- 단방향 연관관계 두 개로 양방향을 설정
@Entity
@Table(name = "tutor")
public class Tutor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
>
private String name;
// N:1 단방향 연관관계 설정
@ManyToOne
@JoinColumn(name = "company_id")
private Company company;
>
// 기본 생성자, getter/setter
}
@Entity
@Table(name = "company")
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
>
private String name;
>
// null을 방지하기 위해 ArrayList로 초기화
// Tutor 클래스의 company 필드와 매핑
@OneToMany(mappedBy = "company")
private List<Tutor> tutors = new ArrayList<>();
>
// 기본 생성자, getter/setter
}
mappedBy
는 양방향 연관관계 설정 시 연관관계의 주인이 아닌 쪽에 선언. 이를 통해 외래 키 관리 책임을 주인 엔티티에 두고 매핑이 중복되지 않도록 함.
- Tutor의 Company를 수정할 때 FK 수정
- Company의 Tutor를 수정할 때 FK 수정
- Tutor가 새로운 Company를 간다면
- Tutor가 참조하는 Company 수정
- Company가 참조하는 List<Tutor> 수정
- DB 입장에서는 FK만 수정되면 되기 때문에 한 쪽에서만 FK를 관리해야함
- 양방향 연관관계 규칙
1. 두 개의 엔티티 중 하나를 연관관계의 주인으로 설정해야 함
- 연관관계의 주인은
mappedBy
속성을 사용하지 않음- 연관관계의 주인이 아니면
mappedBy
속성을 사용- 연관관계의 주인이 아니면 조회만 가능
- 연관관계의 주인만 외래키를 관리(등록, 수정)
- 연관관계의 주인 선정 기준
- 외래키가 있는 곳을 연관관계의 주인으로 지정
- Company가 주인인 경우
- Company를 수정할 때 Tutor를 수정하는 SQL이 실행되기 때문에 두 번의 SQL이 실행되어야 하므로 혼동되기 쉬움