JPA 엔티티 파일 생성 방법: 기본에서 고급까지

Seong Hyeon Kim·2024년 7월 31일
0

스프링

목록 보기
7/9

JPA 엔티티 파일 생성 방법: 기본에서 고급까지

JPA 엔티티는 Java 클래스를 데이터베이스 테이블에 매핑하는 중요한 도구입니다. 초심자부터 고급 사용자까지, JPA 엔티티를 생성하는 다양한 방법을 비교해보겠습니다.

1. 기본 엔티티 생성 방법

기본적으로 JPA 엔티티는 다음과 같은 방식으로 생성할 수 있습니다. 이는 가장 단순한 형태로, 각 필드는 데이터베이스의 컬럼과 매핑됩니다.

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
public class Product {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    
    private Long price;
    
    private String imageUrl;
    
    private LocalDateTime createdAt;
    
    // Getters and Setters
}

기본 방식의 특징

  • 간단하고 직관적: 데이터베이스의 각 컬럼을 필드로 단순 매핑.
  • 초기 학습 곡선이 낮음: JPA 엔티티를 처음 사용하는 개발자에게 적합.
  • 복잡한 관계 매핑 불가: 다른 테이블과의 관계를 매핑할 수 없음.




2. 관계 매핑을 포함한 고급 엔티티 생성 방법

기본 방식에서 더 나아가, 다른 엔티티와의 관계를 정의할 수 있습니다. 다음은 Order 엔티티를 예로 들어, 고객(Customer)과 상품(Product) 엔티티와의 관계를 매핑하는 방법입니다.

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "orders")
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "customer_id", nullable = false)
    private Customer customer;

    @ManyToOne
    @JoinColumn(name = "product_id")
    private Product product;

    @Column(name = "order_date", nullable = false)
    private LocalDateTime orderDate;

    // 기본 생성자
    public Order() {}

    // 매개변수를 가진 생성자
    public Order(Customer customer, Product product, LocalDateTime orderDate) {
        this.customer = customer;
        this.product = product;
        this.orderDate = orderDate;
    }

    // Getters and Setters
}

ManyToOne 어노테이션

  • @ManyToOne: 이는 다대일 관계를 나타냅니다. 즉, 여러 Order가 하나의 Customer에 연결될 수 있습니다.
    • 사용 이유: 이 어노테이션은 데이터베이스의 외래 키(Foreign Key) 관계를 설정하는 데 사용됩니다.
    • 예시: 여러 주문(Order)이 하나의 고객(Customer)에 연결될 때 사용됩니다.

JoinColumn 어노테이션

  • @JoinColumn(name = "customer_id", nullable = false): 외래 키 컬럼의 이름을 지정하고 해당 컬럼이 null이 될 수 없음을 지정합니다.
    • name: 데이터베이스 테이블에서 외래 키 컬럼의 이름을 지정합니다. 이 경우 customer_id로 설정합니다.
    • nullable: 이 컬럼이 null이 될 수 있는지 여부를 지정합니다. false로 설정하면 반드시 값이 있어야 합니다.
    • 기본 동작: @JoinColumn을 사용하지 않으면 JPA는 기본적으로 필드 이름을 사용하여 외래 키 컬럼 이름을 설정하고 참조 엔티티의 기본 키 컬럼을 참조합니다.

매개변수를 가진 생성자

  • 매개변수를 가진 생성자: 엔티티를 쉽게 초기화할 수 있도록 여러 필드를 한 번에 설정할 수 있습니다.
    • 이점:
      • 편리한 객체 초기화: 여러 필드를 한 번에 초기화할 수 있어 코드가 간결해지고 가독성이 좋아집니다.
      • 불변 객체 생성: 객체 생성 후 필드를 변경하지 않도록 할 수 있습니다.
      • 테스트 용이성: 테스트 코드를 작성할 때 간편하게 객체를 생성할 수 있습니다.

매개변수를 가진 생성자는 엔티티를 보다 편리하게 초기화하기 위해 추가됩니다. JPA 엔티티에서 기본 생성자는 필수이지만, 매개변수를 가진 생성자는 선택 사항입니다. 다음은 매개변수 생성자의 사용 목적과 필요성에 대한 설명입니다.

매개변수 생성자의 목적

  1. 편리한 객체 초기화:

    • 매개변수를 가진 생성자를 사용하면 엔티티 객체를 보다 쉽게 초기화할 수 있습니다. 여러 필드를 한 번에 설정할 수 있으므로 코드가 간결해지고 명확해집니다.
  2. 불변 객체:

    • 객체 생성 후 필드를 변경하지 않도록 불변 객체를 만들 때 사용됩니다. 이는 특히 값 객체(value object)에서 유용합니다.
  3. 테스트 용이성:

    • 테스트 코드를 작성할 때 매개변수를 가진 생성자를 사용하면 테스트 데이터를 쉽게 만들 수 있습니다.

예시

매개변수를 가진 생성자를 사용하지 않는 경우:

Shipping shipping = new Shipping();
shipping.setCourierId(1L);
shipping.setTrackingNumber("123456789");
shipping.setSummary("Package summary");
shipping.setPrice(100);
shipping.setDestination("123 Main St");
shipping.setRequests("Leave at front door");
shipping.setStatus("inTransit");
shipping.setCompletedAt(LocalDateTime.now().plusDays(1));
shipping.setAlimtalkSent(true);

매개변수를 가진 생성자를 사용하는 경우:

Shipping shipping = new Shipping(1L, "123456789", "Package summary", 100, "123 Main St", "Leave at front door", "inTransit", LocalDateTime.now().plusDays(1), true);

위 두 예시를 비교해보면, 매개변수를 가진 생성자를 사용한 두 번째 예시가 더 간결하고 명확합니다.

매개변수 결론

매개변수를 가진 생성자는 엔티티 객체를 쉽게 초기화하고 코드의 가독성을 높이는 데 유용합니다. 그러나 이는 선택 사항이며, 기본 생성자와 setter 메소드만으로도 서버가 정상적으로 동작하는 데 지장이 없습니다. 따라서, 매개변수를 가진 생성자는 주로 개발 편의성과 코드의 가독성을 높이기 위해 사용됩니다. 필요에 따라 추가하거나 제거할 수 있습니다.





고급 방식의 예시: 다대다 관계

때로는 엔티티 간의 다대다 관계를 매핑해야 할 때도 있습니다. 예를 들어, 학생(Student)과 수업(Course) 간의 다대다 관계를 정의할 수 있습니다.

Student 엔티티

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id")
    )
    private Set<Course> courses = new HashSet<>();

    // 기본 생성자 및 매개변수를 가진 생성자
    public Student() {}

    public Student(String name) {
        this.name = name;
    }

    // Getters and Setters
}

Course 엔티티

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @ManyToMany(mappedBy = "courses")
    private Set<Student> students = new HashSet<>();

    // 기본 생성자 및 매개변수를 가진 생성자
    public Course() {}

    public Course(String title) {
        this.title = title;
    }

    // Getters and Setters
}

JoinTable 어노테이션

  • @JoinTable: 다대다 관계를 나타내며, 중간 테이블을 정의합니다.
    • name: 중간 테이블의 이름을 지정합니다.
    • joinColumns: 현재 엔티티(Student)의 외래 키 컬럼을 지정합니다.
    • inverseJoinColumns: 반대 엔티티(Course)의 외래 키 컬럼을 지정합니다.

결론

  • 기본적인 JPA 엔티티 생성 방식은 간단하고 직관적이지만, 실제 애플리케이션 개발에서는 엔티티 간의 관계를 매핑하는 것이 중요합니다.
  • 이를 통해 데이터베이스의 데이터 무결성을 유지하고, 복잡한 쿼리도 쉽게 작성할 수 있습니다.
  • 고급 매핑 방식을 사용하면 코드의 재사용성과 유연성을 높일 수 있습니다. 따라서, 개발 초기에는 기본 방식을 사용하고, 점차 고급 방식을 도입하여 엔티티 간의 관계를 정의하는 것이 좋습니다.
profile
삽질도 100번 하면 요령이 생긴다. 부족한 건 경험으로 채우는 개발자

0개의 댓글