java, jpa 공부중
조인전략 JOINED (공통속성은 하나의 테이블로 묶고, 개별속성은 각 테이블에 넣되, 조인해서 사용하는 방법)단일테이블전략 SINGLE_TABLE (한 테이블에 속성들을 다 넣는 방법)구현 클래스마다 테이블 전략 TABLE_PER_CLASS (공통속성으로 묶지않고 각각의 테이블이 속성을 다 갖고 있는 방법)package jpabook.jpashop.domain;
import jakarta.persistence.*;
@Entity
public class Item {
@Id
@GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
package jpabook.jpashop.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Album extends Item{
private String artist;
}
package jpabook.jpashop.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Book extends Item{
private String author;
private String isbn;
}
package jpabook.jpashop.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Movie extends Item{
private String director;
private String actor;
}
위와 같이 item을 상속받는 Album, Book, Movie. jpa의 기본전략이 단일테이블전략 SINGLE_TABLE 을 사용한다.
Hibernate:
create table ITEM (
price integer not null,
ITEM_ID bigint not null,
DTYPE varchar(31) not null,
actor varchar(255),
artist varchar(255),
author varchar(255),
director varchar(255),
isbn varchar(255),
name varchar(255),
primary key (ITEM_ID)
)
전략 변경 방법
- 부모클래스에 어노테이션을 붙여서 전략을 변경할 수 있음.
1. 조인 전략
@Entity @Inheritance( strategy = InheritanceType.JOINED) //조인 전략 @DiscriminatorColumn // DTYPE (name을 안적으면 기본 DTYPE 컬럼이 생성됨. 들어가는 값은 자식클래스의 엔티티명) public class Item { ... } // @DiscriminatorColumn 에 이어서 자식클래스 @Entity @DiscriminatorColumn("A") //자식클래스의 엔티티명이 아닌 별도 지정해주고싶으면 이 어노테이션 넣으면 됨. public class Album extends Item{ private String artist; }
- 각 테이블 create 후 alter add 쿼리가 실행되어 외래 키 설정을 해줌. (일부 채취)
값을 넣어보면Movie movie = new Movie(); movie.setActor("크리스틴 스튜어트"); movie.setDirector("로즈 글래스"); movie.setName("러브 라이즈 블리딩"); movie.setPrice(10000); em.persist(movie); tx.commit();
조회하면 join처리해서 가져옴.
2. 단일 테이블 전략
@Entity @Inheritance( strategy = InheritanceType.SINGLE_TABLE) // 여기만 바꾸면됨. // @DiscriminatorColumn 단일 테이블 전략에서는 안적어도 DTYPE이 자동으로 생성됨. public class Item { ... }
3. 구현 클래스마다 테이블 전략
@Entity @Inheritance( strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Item { ... }추상클래스로 만들면 item테이블은 안만들어지고 나머지 자식클래스들만 만들어짐.
insert할 때는 각 테이블에만 쿼리가 날라가고, 조회할 때도 각 테이블에서만 조회가 된다. 조회할 때도 각 해당되는 객체를 통해서 조회하면 문제가 되지않지만, 부모클래스(item)에서 조회를 하려고 하면 온 갖 union쿼리 실행되면서 복잡해진다.
장점
단점
장점
단점
장점
단점
공통 매핑 정보가 필요할 때 사용(id, name)
테이블 간 연관관계가 있는건 아니고 그냥 id, name같은 계속 반복되는걸 기본엔티티를 가지고 상속받아서 쓰면 덜 피곤하니까 그럴려고 만든거임. 공통 속성모아서 상속해서 쓰려고 만든거.
상속관계 매핑X
엔티티X, 테이블과 매핑X
부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
조회, 검색 불가(em.find(BaseEntity) 불가)
직접 생성해서 사용할 일이 없으므로 추상 클래스 권장
테이블과 관계 없고,
단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할
주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통 으로 적용하는 정보를 모을 때 사용
참고: @Entity 클래스는 엔티티나 @MappedSuperclass로 지 정한 클래스만 상속 가능
package jpabook.jpashop.domain;
import jakarta.persistence.MappedSuperclass;
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy; //공통 속성
}
public class Item extends BaseEntity{
...
}

package jpabook.jpashop.domain;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "MEMBER")
public class Member extends BaseEntity{
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
private String name;
private String city;
private String street;
private String zipcode;
@OneToMany(mappedBy = "member")
private List<Order> order = new ArrayList<>();
}
package jpabook.jpashop.domain;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@MappedSuperclass
public abstract class BaseEntity {
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
public LocalDateTime getCreatedDate() {
return createdDate;
}
public void setCreatedDate(LocalDateTime createdDate) {
this.createdDate = createdDate;
}
public LocalDateTime getUpdatedDate() {
return updatedDate;
}
public void setUpdatedDate(LocalDateTime updatedDate) {
this.updatedDate = updatedDate;
}
}
package jpabook.jpashop.domain;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "ORDERS")
public class Order extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "ORDER_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>();
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus status;
@OneToOne
@JoinColumn(name = "DELIVERY_ID")
private Delivery delivery;
}
package jpabook.jpashop.domain;
import jakarta.persistence.*;
@Entity
@Table(name = "ORDER_ITEM")
public class OrderItem extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "ORDER_ITEM_ID")
private Long id;
@ManyToOne
@JoinColumn(name = "ITEM_ID")
private Item item;
@ManyToOne
@JoinColumn(name = "ORDER_ID")
private Order order;
private int orderPrice;
private int count;
}
package jpabook.jpashop.domain;
public enum OrderStatus {
PENDING, ORDER, CANCEL
}
package jpabook.jpashop.domain;
import jakarta.persistence.*;
@Entity
@Table(name = "DELIVERY")
public class Delivery extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "DELIVERY_ID")
private Long id;
@OneToOne(mappedBy = "delivery")
private Order order;
private String city;
private String zipcode;
@Enumerated
private DeliveryStatus status;
}
package jpabook.jpashop.domain;
public enum DeliveryStatus {
PENDING, DELIVERING, COMPLETE
}
package jpabook.jpashop.domain;
import jakarta.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Inheritance( strategy = InheritanceType.SINGLE_TABLE)
public abstract class Item extends BaseEntity{
@Id
@GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
}
package jpabook.jpashop.domain;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Album extends Item{
private String artist;
private String etc;
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getEtc() {
return etc;
}
public void setEtc(String etc) {
this.etc = etc;
}
}
package jpabook.jpashop.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Movie extends Item{
private String director;
private String actor;
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
package jpabook.jpashop.domain;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
public class Book extends Item{
private String author;
private String isbn;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
}