[JPA] JPA 간단 정리 및 엔티티 클래스 개발
JPA를 공부하고자 다음 강의를 들으며 학습한 내용을 정리하고 공부해나가고자 한다👩💻
공부를 하면서 더 알게되거나 추가되는 내용이 있다면 계속 업데이트 할 예정이다!
엔티티 클래스 개발 정리에 들어가기 전, JPA는 무엇인지 간단한 정리를 하고자 한다.
JPA란?
JPA란 스프링에서 많이 사용하지만, 스프링이 제공하는 API가 아닌 자바가 제공하는 API다. 자바 ORM 기술에 대한 표준 명세로, 자바 어플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스다.
그렇다면 ORM(Object Relational Mapping)이란 무엇일까?!
ORM 프레임워크는 자바 객체와 관계형 DB를 매핑한다. 즉 객체가 DB 테이블이 되도록 만들어주 는 것이다. ORM을 사용하면 SQL을 작성하지 않아도 직관적인 메소드로 데이터를 조작할 수 있다는 장점이 있다. 대표적인 것으로 Hibernate가 있다. 스프링부트에서는 spring-boot-starter-data-jpa 패키지를 가져와 사용가능하며, Hibernate프레임워크를 활용한다. JPA는 애플리케이션과 JDBC 사이에서 동작하며, 개발자가 JPA를 활용했을 때, JDBC API를 통해 SQL을 호출하여 데이터베이스와 호출하는 전개가 이루어진다.
JPA 특징
1) 객체 중심 개발 가능
- SQL 중심 개발이 이루어진다면, CRUD작업이 반복해서 이루어진다. 하나의 테이블을 생성해야 할 때, 이에 해당하는 CRUD를 전부 만들어야 하며, 추후에 컬럼이 생성되면 관련 SQL을 모두 수정해야하는 번거로움이 있고, 실수할 가능성도 높아진다.
2) 생산성 증가
SQL 쿼리를 직접 생성하지 않고, 만들어진 객체에 JPA 메소드를 활용해 데이터베이스를 다루기 때문에 개발자에게 매우 편리성을 제공해준다.
3) 유지보수 용이
쿼리 수정이 필요할 때, 이를 담는 DTO 필드도 모두 변경해야 하는 작업이 필요하지만 JPA에서는 엔티티 클래스 정보만 변경하면 된다.
4) 성능증가
JPA는 동일한 쿼리에 대한 캐시기능을 지원해주기 때문에 비교적 높은 성능 효율을 경험할 수 있다.
도메인 모델과 테이블 설계
다음 설계를 통해 알 수 있는 것들은 다음과 같다.
1) 회원은 여러 상품을 주문할 수 있다.
2) 한 번 주문할 때 여러 상품을 선택할 수 있다.
3) 상품은 공통 속성을 사용하므로 상속구조로 되어 있다.
엔티티 개발
- 실무에서 Setter 어노테이션은 지양해야한다!
@Entity
@Getter@Setter
public Class Member{
@Id @GeneratedValue
@Column(name="member_id")
private Long id;
private String name;
@Embedded
private Address address;
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
}
@Entity
@Table(name = "orders")
@Getter @Setter
public class Order{
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "member_id")
private Member member; // 연관관계의 주인
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = LAZY)
@JoinColumn(name = "delivery_id")
private Delivery delivery;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus orderStatus;
}
@Embeddable
@Getter
public class Address{
private String city;
private String street;
private String zipcode;
}
@Entity
@Getter @Setter
public class Delivery{
@Id @GeneratedValue
@Column(name = "delivery_id")
private Long id;
@OneToOne(fetch = LAZY, mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING)
private DeliveryStatus status;
}
@Entity
@Getter @Setter
public class OrderItem{
@Id @GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "item_id")
private Item item;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice;
private int count;
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DisCriminatorColumn(name = "dtype")
@Getter @Setter
public abstract class Item{
@Id @GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private String stockQuantity;
@ManyToMany
private List<Category> categories = new ArrayList<>();
}
@Entity
@DiscriminatorValue("A")
@Getter @Setter
public class Album extends Item{
private String artist;
private String etc;
}
@Entity
@DiscriminatorValue("B")
@Getter @Setter
public class Book extends Item{
private String author;
private String isbn;
}
@Entity
@DiscriminatorValue("M")
@Getter @Setter
public class Movie{
private String director;
private String actor;
}
@Entity
@Getter @Setter
public class Category{
@Id @GeneratedValue
@Column(name = "category_id")
private Long id;
private String name;
@ManyToMany(fetch = LAZY)
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
}
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 - 인프런 | 강의
실무에 가까운 예제로, 스프링 부트와 JPA를 활용해서 웹 애플리케이션을 설계하고 개발합니다. 이 과정을 통해 스프링 부트와 JPA를 실무에서 어떻게 활용해야 하는지 이해할 수 있습니다., - 강
www.inflearn.com