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.)