반응형
이번 포스트에서는 엔티티에 대해서 알아보자
1. 엔티티(Entity)
- 엔티티는 JPA가 데이터베이스와 상호작용하는데 필요한 주요 객체이다.
- 엔티티는 실제로 데이터베이스 테이블의 하나의 레코드를 나타내는 자바 객체이다. 이 엔티티는 데이터베이스에서 정보를 읽고, 변경하고, 생성하고, 삭제하는 모든 작업에 사용된다.
2. 엔티티를 만들기 위한 규칙
- 클래스 상단에 @Entity 어노테이션 적기
- 엔티티 클래스는 @Entity라는 어노테이션을 클래스에 표시해야 한다. 이것이 없으면 JPA는 이것을 엔티티로 인식하지 못한다.
- 엔티티 클래스는 @Entity라는 어노테이션을 클래스에 표시해야 한다. 이것이 없으면 JPA는 이것을 엔티티로 인식하지 못한다.
- 기본 키:
- 반드시 기본 키(@Id 어노테이션이 붙은 필드)를 가지고 있어야 한다. 기본 키는 데이터베이스 테이블에서 각 레코드를 고유하게 식별하는 데(pk로) 사용된다.
- 반드시 기본 키(@Id 어노테이션이 붙은 필드)를 가지고 있어야 한다. 기본 키는 데이터베이스 테이블에서 각 레코드를 고유하게 식별하는 데(pk로) 사용된다.
- 기본 생성자:
- JPA 스펙에 따르면 엔티티 클래스는 public 또는 protected 범위의 기본 생성자를 가져야 한다. 이렇게 하면 JPA 구현체가 엔티티 인스턴스를 생성할 때 리플렉션을 통해 이 기본 생성자를 사용할 수 있다. 그러므로 엔티티 클래스를 작성할 때는 반드시 이 점을 고려해야 한다.
- 자바는 기본적으로 기본 생성자를 만들어주지만 접근제어를 위해 주로 lombok을 사용해서 아래와 같이 적어준다.
@NoArgsConstructor(access = AccessLevel.PROTECTED)
- 최상위 클래스 or MappedSuperclass
- 엔티티 클래스의 구조는 최상위 클래스이여야 하며 MappedSuperclass또는 다른 엔티티를 extends로 상속을 받을수가 있다
- 엔티티 클래스의 구조는 최상위 클래스이여야 하며 MappedSuperclass또는 다른 엔티티를 extends로 상속을 받을수가 있다
- 엔티티 클래스의 코드구성
- 엔티티 클래스는 비즈니스 로직을 포함할 수 있지만, 가능한 상태와 행동을 나타내는 것에 초점을 맞춰야 한다.
- 예를 들어, 아래와 같은 Member 엔티티가 있다고 가정해보자.
@Entity
public class Member {
@Id
private Long id;
private String username;
// Getter, Setter ...
}
- 위 코드에서 클래스 상단에 적어준 @Entity 어노테이션을 통해 JPA에게 이 클래스를 엔티티로 인식하게 한다.
- 필드 위의 @Id 어노테이션은 해당 필드가 테이블의 PK(Primary Key)임을 나타낸다. 이렇게 각 필드는 테이블의 컬럼과 매핑된다.
위 예시 코드에 생성자가 없는이유
- 자바에서 클래스를 선언할 때 명시적으로 생성자를 지정하지 않으면, 컴파일러는 인자가 없는 기본 생성자를 자동으로 추가해준다. 이를 "디폴트 생성자" 또는 "기본 생성자"라고 부른다.
- 그러나 만약 클래스에 하나 이상의 생성자가 명시적으로 정의되어 있다면, 컴파일러는 자동으로 기본 생성자를 추가하지 않는다. 이 때는 명시적으로 기본 생성자를 추가해주어야 한다.
엔티티를 적용시킨 코드 예시
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "members") // members 테이블과 매핑
@Entity // 해당 클래스가 JPA 엔티티임을 나타냄
public class Member {
@Id // 기본 키(primary key) 필드임을 나타냄
@GeneratedValue(strategy = GenerationType.IDENTITY) // 기본 키 값을 자동으로 생성하는 전략을 지정
@Column(name = "member_id") // 필드를 데이터베이스 테이블의 member_id 컬럼과 매핑
private Long id; // id 필드
@Column(name = "username") // 필드를 데이터베이스 테이블의 username 컬럼과 매핑
private String username; // username 필드
@ManyToOne // 다대일 관계를 매핑
@JoinColumn(name = "team_id") // team_id 외래 키 컬럼과 매핑
private Team team; // team 필드
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
// Member와 일대다 관계를 매핑. Order 엔티티의 member 필드와 연결됨.
// CascadeType.ALL은 연관된 엔티티에 대해 모든 작업을 전파한다는 의미
private List<Order> orders; // orders 필드
// Getter, Setter ...
}
3. 엔티티 매핑
- 엔티티 매핑은 데이터베이스의 테이블과 자바 객체(엔티티)를 연결하는 과정을 말한다. 이는 JPA에서 제공하는 다양한 어노테이션들을 사용하여 이루어진다. 주요 어노테이션은 다음과 같다.
- @Entity: JPA가 관리하는 엔티티 클래스임을 나타낸다. 이 어노테이션을 통해 해당 클래스는 테이블과 매핑된다는 것을 JPA에게 알린다.
- @Table: 엔티티와 매핑할 테이블을 지정한다. 생략하면 클래스 이름을 테이블 이름으로 사용한다.
- @Id: 테이블의 기본 키에 매핑한다.
- @Column: 필드를 테이블의 컬럼에 매핑한다. 생략하면 필드 이름을 컬럼 이름으로 사용한다.
- @JoinColumn: 외래 키를 매핑할 때 사용한다.
- @ManyToOne, @OneToMany, @OneToOne, @ManyToMany: 관계형 데이터베이스의 관계를 나타낸다.
엔티티 매핑 코드 예시
// @Entity 어노테이션을 이용해서 해당 클래스가 엔티티임을 표시
@Entity
// @Table 어노테이션을 이용해서 해당 엔티티가 매핑될 테이블을 지정 (생략시 클래스 이름을 테이블 이름으로 사용)
@Table(name = "members")
public class Member {
// @Id 어노테이션을 이용해 해당 필드가 기본키임을 나타냄
@Id
// @GeneratedValue 어노테이션은 기본키 생성을 데이터베이스에 위임함.
// IDENTITY 전략은 데이터베이스에 기본키 생성을 위임하는 전략 (예: MySQL, PostgreSQL)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// @Column 어노테이션은 필드를 테이블의 컬럼에 매핑함. 생략하면 필드 이름을 컬럼 이름으로 사용함.
@Column(name = "username")
private String username;
// 관계형 매핑 어노테이션. @ManyToOne은 다대일 관계를 매핑함.
// 여기서는 여러 개의 Member가 하나의 Order에 속할 수 있음을 나타냄.
@ManyToOne
// @JoinColumn 어노테이션은 외래키 매핑 시 사용됨. 여기서는 order_id가 외래키임을 표시.
@JoinColumn(name = "order_id")
private Order order;
// Getter, Setter ...
}
- @ManyToOne 어노테이션은 "다대일" 관계를 매핑한다.
- 즉, 여기에선 여러 Member 엔티티 인스턴스가 하나의 Order 엔티티 인스턴스를 참조할 수 있다. 반대로, @OneToMany 어노테이션은 "일대다" 관계를 매핑하며, 이는 하나의 엔티티 인스턴스가 여러 엔티티 인스턴스를 참조할 수 있음을 나타낸다. 이러한 관계들은 JPA가 데이터베이스의 관계형 모델을 객체 지향 모델로 잘 매핑하도록 해준다.
2023.08.13 - [JPA] - Spring - JPA 영속성 컨텍스트(EntityManager)
반응형
'Spring Data JPA' 카테고리의 다른 글
Spring JPA - 엔티티를 DTO로 바꿔서 사용하는 이유 (0) | 2023.08.13 |
---|---|
Spring JPA - 연관관계 매핑 (0) | 2023.08.13 |
Spring JPA 영속성 컨텍스트(EntityManager) (0) | 2023.08.13 |
Spring JPA [SpringBoot3.1] - Querydsl 사용 (0) | 2023.08.08 |
Spring JPA [SpringBoot3.x.x] - Querydsl 적용하고 빌드하기 (0) | 2023.08.08 |