W8D3(2) - JPA
고급 매핑
JPA는 RDB의 테이블과 매핑된 객체(Entity)를 객체답게 사용할 수 있도록 여러가지 고급 매핑 전략을 제공해줍니다.
1. 상속관계매핑
(1) 조인테이블 전략
JPA는 RDB의 테이블과 매핑된 객체(Entity)를 객체답게 사용할 수 있도록 여러가지 고급 매핑 전략을 제공해줍니다.

- 
Item을 상속받고 있는 Car, Furniture, Food 객체 
- 
부모 클래스에는 @Inheritance를 쓰고 전략을 적어준다 
  
- 
데이터가 잘 저장되는지 테스트 해보기 
@Slf4j
@SpringBootTest
public class ImproveMappingTest {
    @Autowired
    private EntityManagerFactory emf;
    @Test
    void inheritance_test(){
        EntityManager entityManager = emf.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Food food = new Food();
        food.setPrice(2000);
        food.setStockQuantity(200);
        food.setChef("백종원");
         entityManager.persist(food);
         transaction.commit();
    }
 }
- 실행결과를 보면 item과 food 둘다 insert문이 들어가는 것을 확인할수있음
(2) 싱글테이블 전략

- Single_TABLE 전략으로 바꿔준다
- 싱글테이블 전략은 하나의 테이블에 모든 정보를 담고 있기 때문에 각 객체를 구분해 줄수 있는 정보 필요 (@DiscriminationColum)
- DiscriminatorValue는 부모객체에서 명시해준 DTYPE 컬럼에 값으로 들어감
  
 @Test
    void inheritance_test(){
        EntityManager entityManager = emf.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Food food = new Food();
        food.setPrice(2000);
        food.setStockQuantity(200);
        food.setChef("백종원");
         entityManager.persist(food);
         transaction.commit();
    }- 결과와 데이터베이스를 확인해보면 하나의 테이블로 생성되는 것을 볼수있음
- Food를 저장했기때문에 데이터베이스의 DTYPE 컬럽에 food 값으로 저장
  
2. @MappedSupserclass
- 공통으로 사용하는 필드들을 관리로 할때 공통 엔테티로 뽑아서 자주 사용

@Test
    void mapped_super_class_test(){
        EntityManager entityManager = emf.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Order order = new Order();
        order.setUuid(UUID.randomUUID().toString());
        order.setOrderStatus(OrderStatus.OPENED);
        order.setMemo("---");
        order.setOrderDatetime(LocalDateTime.now());
        //
        order.setCreatedBy("ChaeWon");
        order.setCratedAt(LocalDateTime.now());
        entityManager.persist(order);
        transaction.commit();
    }
3. 식별자 클래스
- 
pk값을 하나가아니라 복합키로 구분해야할때 사용 
- 
어떤값을 식별자로 써서 equals 돌려야할지 모르기때문에 런타임에러 
- 
JPA에서 식별자를 둘 이상 사용하려면 별도의 식별자 클래스를 만들어야 한다. 
public class Member {
	@Id
	private String id1;
	@Id
	private String id2; // runtime error
}(1) @IdClass
@Getter
@Setter
@Entity
@IdClass(ParentId.class)
public class Parent {
    @Id
    private String id1;
    @Id
    private String id2;
}
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
public class ParentId implements Serializable {
    private String id1;
    private String id2;
}@Test
void multi_key_test() {
    EntityManager entityManager = emf.createEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Parent parent = new Parent();
    parent.setId1("id1");
    parent.setId2("id2");
    entityManager.persist(parent);
    transaction.commit();
    Parent entity = entityManager.find(Parent.class, new ParentId("id1", "id2"));
    log.info("{}, {}", entity.getId1(), entity.getId2());
}- Serializable 인터페이스를 구현해야 한다.
- eqauls, hashCode를 구현해야 한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public 이어야 한다.

@EmbeddedId
@Getter
@Setter
@Entity
public class Parent2 {
    @EmbeddedId
    private ParentId2 id;
}
@Getter
@Setter
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class ParentId2 implements Serializable {
    private String id1;
    private String id2;
} @Test
    void id_test(){
        EntityManager entityManager = emf.createEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Parent parent = new Parent();
        parent.setId(new ParentId("id1", "id2"));
        entityManager.persist(parent);
        transaction.commit();
        entityManager.clear();
        Parent parent1 = entityManager.find(Parent.class, new ParentId("id1", "id2"));
        log.info("{}, {}", parent1.getId().getId1(), parent1.getId().getId2());
    }
    }- Serializable 인터페이스를 구현해야 한다.
- eqauls, hashCode를 구현해야 한다.
- 기본 생성자가 있어야 한다.
- 식별자 클래스는 public 이어야 한다.
- @Embeddable 애노테이션이 있어야 한다.
Author And Source
이 문제에 관하여(W8D3(2) - JPA), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kcwthing1210/W8D32-JPA저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)