<엔티티 클래스 개발2>
#파일구조
Category
//카테고리 엔티티
@Entity
@Getter @Setter
public class Category {
//pk
@Id @GeneratedValue
@Column(name="category_id")
private Long id;
private String name;
@ManyToMany // Category엔티티도 List로 items을 가지고, item엔티티도 List로 Category를 가진다.
//일대다 다대일로 풀어내는 중간테이블이 존재하기 때문에 테이블로 매핑해줘야한다
@JoinTable(name = "category_item", //중간테이블 이름 정하기
//매핑
joinColumns = @JoinColumn(name = "category_id"),//중간테이블과 category테이블 join (fk)
inverseJoinColumns = @JoinColumn(name = "item_id") //중간테이블에서 item테이블 join (fk)
)
private List<Item> items = new ArrayList<>();
//밑의 둘은 같은 엔티티를 셀프로 양방향 연관관계 매핑
@ManyToOne
@JoinColumn(name ="parent_id") //fk
private Category parent;
//자식 여러명 가능
@OneToMany(mappedBy = "parent") // private Category parent; 여기로 이동
private List<Category> child = new ArrayList<>();
}
이제 작성 끝 실행하기
Address (주소 값 타입)
참고: 값 타입은 변경 불가능하게 설계해야 한다.
-> @Setter 를 제거하고, 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들자.
//주소
//@Embeddable //JPA의 내장 타입 Member에 썼으니 안써도..
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
/*
JPA 스펙상 엔티티나 임베디드 타입( @Embeddable )은
자바 기본 생성자(default constructor)를
public 또는 protected 로 설정해야 한다.
->> JPA가 이런 제약을 두는 이유는
JPA 구현 라이브러리가 객체를 생성할 때 리플랙션 같은 기술을 사용할 수 있도록 지원해야 하므로
*/
protected Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
#실무에서는?
실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천
> 이론적으로 Getter, Setter 모두 제공하지 않고, 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적이다.
하지만 실무에서 엔티티의 데이터는 조회할 일이 너무 많으므로, Getter의 경우 모두 열어두는 것이 편리하다.
Getter는 아무리 호출해도 호출 하는 것 만으로 어떤 일이 발생하지는 않는다.
하지만 Setter는 문제가 다르다. Setter를 호출하면 데이터가 변한다.
Setter가 모두 열려있으면 변경 포인트가 너무 많아서, 유지보수가 어렵다.
Setter를 막 열어두면 가까운 미래에 엔티티가 도대체 왜 변경되는지 추적하기 점점 힘들어진다.
그래서 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확 하도록 변경을 위한 비즈니스 메서드를 별도로 제공하자. 혹은 나중에 리펙토링으로 제거하자.
실무에서는 @ManyToMany 를 사용하지 말자
> @ManyToMany 는 편리한 것 같지만, 중간 테이블( CATEGORY_ITEM )에 컬럼을 추가할 수 없고,
세밀하게 쿼리를 실행하기 어렵기 때문에 실무에서 사용하기에는 한계가 있다.
중간 엔티티( CategoryItem ) 를 만들고 @ManyToOne , @OneToMany 로 매핑해서 사용한다.
정리하면 대다대 매핑을 일대다, 다대일 매핑으로 풀어내 사용하자.
'WEB JAVA SPRING > PROJECT' 카테고리의 다른 글
[Day-7] 회원 도메인, 리포지토리, 서비스, 회원 기능 테스트 (0) | 2023.08.25 |
---|---|
[Day-6] 엔티티 설계 (연관관계) (0) | 2023.08.25 |
[Day-4] 도메인 모델과 테이블 설계, 엔티티 클래스 개발 1 (0) | 2023.08.25 |
[Day-3] JPA와 DB설정, 동작확인 (0) | 2023.08.25 |
[Day-2] 라이브러리, H2 DB (0) | 2023.08.25 |