🛫 ORM(Object-Relational Mapping)
- 객체와 관계형 DB를 매핑
- 객체를 마치 자바 컬렉션에 저장할 수 있고, 적절한 SQL을 생성해서 DB객체에 저장
🌈JPA(Java Persistance API)
- 자바의 ORM 기술 표준
- 객체를 DB에 저장하고 관리할 떄 개발자가 직접 SQL을 작성하지 않아도 됨
- JPA가 개발자 대신 적절한 SQL을 생성해서 DB에 전달하고 객체를 자동으로 Mapping
- 스프링 부트는 ORM 프레임워크(Hibernate)가 탑제되어 있음
@JoinColumn(name="", referencedColumnName="")
name - 원하는 이름을 마음대로 설정 가능
들어갈 내용: "테이블에 들어갈 컬럼명"
기본값: 필드명_[참조하는테이블의 기본 키 컬럼명]
referencedColumnName - 정확한 값을 넣지 않으면 예외 발생
들어갈 내용: 대상 테이블의 참조하는 컬럼명
기본값: 참조하는 테이블의 기본 키 컬럼명
public class Brand {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx; // 번호
private String name; // 브랜드명
@ToString.Exclude
@OneToMany(fetch = FetchType.LAZY, mappedBy = "brand", cascade = CascadeType.ALL)
private List<Product> products;
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx; // 번호
@ManyToOne
@JoinColumn(name="brand_name", referencedColumn="name")
private Brand brand;
이렇게 되면 테이블에는 아래와 같이 들어간다고 생각하시면 됩니다!
idx | brand_name | -- 내가 정한이름
1 | nike | -- 예시(name을 foreign key로 설정)
만약에 아무것도 안쓰고 @JoinColumn만 쓴다면 기본값이 들어가겠죠?
idx | brand_idx | -- 기본값 : 필드명_참조하는테이블 Primary key 컬럼명
1 | 3 | -- brand의 Primary key인 idx
저희는 안전하게 모두 작성을 해준겁니다!
아무리 주인이 아닌 곳에서 객체를 변경해 보아봤자 데이터베이스에는 적용이 안된다. (null값이 들어감)
꼭 연관관계의 주인에 값을 세팅해 주어야 하며, 가급적 두 객체 모두에게 값을 세팅해주도록 하는 것이 좋다.연관관계 주인의 역할: 외래키를 등록, 수정, 삭제 (주인이 아니면 외래키를 읽기만 가능)
연관관계 주인을 세팅 안했을때 문제: 자세한건 위 링크 참고
연관관계의 주인을 지정해주는 속성✨✨
연관관계의 주인은 mappedBy 속성을 사용하지 않는다.
주인이 아니라면 mappedBy 속성을 사용해서 주인이 아님을 설정합니다. 속성의 값으로는 연관관계의 주인을 지정해줍니다.
mappedBy 속성에 들어올 이름은, 연관관계 주인의 해당 속성의 필드명과 일치해야 합니다.
예를들어 Product에서 Brand를 private Brand ipip;라고 설정했다면, Brand에서 @OneToMany(mappedby="ipip")라고 해야합니다.
보통 필드명과 클래스명을 같도록 private Brand brand라고 쓰기때문에, Brand에서 @OneToMany(mappedby="brand")라고 쓴겁니다!
@OneToOne: 하나의 엔티티가 하나의 엔티티와 연관 관계를 맺을 때 사용 1:1
@OneToMany: 하나의 엔티티가 여러개의 엔티티와 연관 관계를 맺을 때 사용 1명이 여러개 주문
@ManyToOne: 여러개의 엔티티가 하나의 엔티티와 연관 관계를 맺을때 ( 위 내용 꺼꾸로)
@ManyToMany: 여러개의 엔티티가 여러개의 엔티티와 연관 관계를 맺을 때 사용
FetchType
- LAZY(지연 로딩)
- 참조 객체들의 데이터들은 무시하고 해당 엔티티의 데이터만을 가져오는 방법
- 참조객체의 데이터를 사용하기 위해 여러번의 쿼리를 사용
- EAGER(즉시 로딩)
- 하나의 객체를 DB로 부터 읽어올 때 참조 객체들의 데이터까지 전부 읽어오는 방식
- 한번의 쿼리로 모든 정보를 가져옴
//파트너 2개 생성 category_id 1L로 설정
//Users entity
@OneToMany(fetch= FetchType.LAZY, mappedBy="users")
private List<OrderGroup> orderGroups;
--------------------------------------------------
//Order group
@JoinColumn(name="user_id") //DB에 저장된 ordergroup user_id와 매칭
@ManyToOne
private Users users;
@OneToMany(fetch = FetchType.LAZY,mappedBy = "orderGroup")
private List<OrderDetail> orderDetails;
---------------------------------------------------
//Order detail
@ManyToOne
private Item item;
@ManyToOne
private OrderGroup orderGroup;
----------------------------------------------------
//Item
@ManyToOne
private Partner partner;
@OneToMany(fetch = FetchType.LAZY,mappedBy = "item")
private List<OrderDetail> orderDetails;
-----------------------------------------------------
//Partner
@ManyToOne
private Category category;
@OneToMany(fetch = FetchType.LAZY,mappedBy = "partner")
private List<Item> items;
-----------------------------------------------------
//category: partner (1:N)
@OneToMany(fetch = FetchType.LAZY,mappedBy = "category")
private List<Partner> partners;