나를 기록하다
article thumbnail
반응형

객체와 테이블

JPA(Java Persistence API)는 자바 어플리케이션에서 관계형 데이터베이스를 사용하기 위한 인터페이스를 제공합니다. 여기서 객체와 테이블 간의 매핑이 중요한데요, 객체는 자바 프로그램에서 사용되는 인스턴스를, 테이블은 데이터베이스에서 데이터를 저장하는 구조를 나타냅니다.

이 매핑은 JPA를 통해 객체와 테이블 사이에 어떻게 데이터를 주고받을 것인지를 정의합니다. 객체와 테이블 간의 관계를 이해하기 위해 간단한 예시를 들겠습니다.

예를 들어, 도서관에서 책과 작가 정보를 관리하는 프로그램을 만든다고 가정해봅시다.

먼저, 자바 프로그램에서 사용할 객체를 만듭니다.

@Entity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String title;
    private String isbn;

    @ManyToOne
    private Author author;
}

@Entity
public class Author {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @OneToMany(mappedBy = "author")
    private List<Book> books;
}

여기서 @Entity는 JPA가 관리하는 객체임을 나타냅니다. @Id@GeneratedValue는 객체의 고유 식별자이며, 데이터베이스의 기본 키(Primary Key)에 대응됩니다. @ManyToOne@OneToMany는 객체 간의 관계를 나타내는데, 이 경우 작가(Author)와 책(Book) 사이의 관계입니다.

이제 테이블 구조를 살펴봅시다. 이 예제에서는 다음과 같은 테이블 구조를 가질 것입니다.

authors
- id (Primary Key)
- name

books
- id (Primary Key)
- title
- isbn
- author_id (Foreign Key)

여기서 authors 테이블은 작가 정보를 저장하며, books 테이블은 책 정보를 저장합니다. 책 테이블의 author_id는 외래 키(Foreign Key)로써, 작가 테이블의 기본 키를 참조합니다.

이처럼 JPA를 사용하면 객체와 테이블 간의 매핑을 쉽게 정의할 수 있으며, SQL 쿼리를 직접 작성하지 않아도 데이터베이스와 통신할 수 있습니다. 이를 통해 개발자는 비즈니스 로직에 집중할 수 있게 됩니다.

 

Item을 상속한 Album 객체 저장 시, Album과 Item에 모두 저장하는 이유

객체 지향 프로그래밍에서 상속은 하위 클래스가 상위 클래스의 속성과 메서드를 물려받는 것을 의미합니다. JPA에서도 상속 관계가 있는 엔티티를 매핑할 수 있는데, 상속 관계 매핑 전략에 따라 테이블 구조와 저장 방식이 달라집니다. 이 경우 Item을 상속한 Album 객체를 저장할 때 Album에도 저장하고 Item에도 저장하는 이유는 "조인 전략"을 사용했기 때문입니다.

조인 전략은 상속 관계의 엔티티를 각각의 테이블에 저장하고, 하위 테이블이 상위 테이블의 기본 키를 외래 키로 갖는 방식입니다. 예를 들어, Item을 상속한 Album 클래스를 보겠습니다.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private int price;
}

@Entity
public class Album extends Item {
    private String artist;
    private String genre;
}

이 경우 다음과 같은 테이블 구조를 가질 것입니다.

items
- id (Primary Key)
- name
- price

albums
- id (Primary Key, Foreign Key)
- artist
- genre

조인 전략을 사용하면 엔티티의 상속 구조와 유사한 테이블 구조를 가질 수 있으며, 각각의 테이블에 데이터를 저장해야 합니다. Album 객체를 저장할 때, Item의 속성을 items 테이블에 저장하고, Album의 속성을 albums 테이블에 저장합니다. 이렇게 하는 이유는 데이터베이스 정규화 원칙을 지키기 위함입니다. 정규화를 통해 중복 데이터를 최소화하고 데이터 무결성을 유지할 수 있습니다.

그러나 이 방식은 성능상의 단점이 있을 수 있습니다. 상속 구조가 복잡할수록 JOIN 연산이 많아져 조회 성능이 저하될 수 있습니다. 이런 경우에는 다른 전략을 사용할 수 있습니다. 예를 들어, 단일 테이블 전략(InheritanceType.SINGLE_TABLE)은 상속 관계의 모든 엔티티를 하나의 테이블에 저장하는 방식입니다. 이 방식은 조회 성능이 빠르지만, 테이블에 NULL 값이 많아져 공간 효율이 떨어질 수 있습니다.

따라서 상속 관계 매핑 전략을 선택할 때 애플리케이션의 요구 사항과 성능에 따라 적절한 전략을 고려해야 합니다.

  1. 조인 전략(InheritanceType.JOINED) : 상속 구조를 그대로 테이블 구조에 반영하고 싶을 때 사용합니다. 정규화 원칙을 지키고 중복 데이터를 최소화할 수 있지만, 조회 성능이 저하될 수 있습니다.
  1. 단일 테이블 전략(InheritanceType.SINGLE_TABLE) : 상속 관계의 모든 엔티티를 하나의 테이블에 저장하는 방식입니다. 조회 성능이 빠르지만, 테이블에 NULL 값이 많아져 공간 효율이 떨어질 수 있습니다.
  1. 구현 클래스마다 테이블 전략(InheritanceType.TABLE_PER_CLASS) : 각 구현 클래스마다 테이블을 생성합니다. 각 테이블은 부모 클래스의 속성과 자식 클래스의 속성을 모두 저장합니다. 이 방식은 조회 성능이 조인 전략에 비해 개선되지만, 중복 데이터가 발생할 수 있습니다.

결국, Album 객체를 저장할 때 Album에도 저장하고 Item에도 저장하는 이유는 조인 전략을 사용했기 때문입니다. 이 전략은 상속 관계의 엔티티를 각각의 테이블에 저장하고, 하위 테이블이 상위 테이블의 기본 키를 외래 키로 갖는 방식입니다. 이 방식을 사용하면 데이터베이스 정규화 원칙을 지키고 데이터 무결성을 유지할 수 있습니다. 하지만 상황에 따라 다른 전략을 사용하는 것이 더 적합할 수도 있으므로, 요구 사항과 성능을 고려하여 전략을 선택해야 합니다.

 

반응형

'Java > JPA' 카테고리의 다른 글

[JPA] JPA 모르는 개념 정리  (0) 2023.04.07
[JPA] Getter and Setter  (0) 2023.04.02
[JPA] Flush  (0) 2023.03.19
[JPA] JPQL의 기초  (0) 2023.03.16
[JPA] JPA 기초설정과 H2 DB 연동  (0) 2023.03.16
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...