Spring-Boot JPA: 연관 관계 구현

연관 관계 구현

고려사항

1. 방향

  • 단방향
  • 양방향

2. 다중성

  • One-to-one
  • One-to-many
  • Many-to-one
  • Many-to-many

3. 양방향 연관 관계의 주인

  • 객체를 양방향 연관 관계로 만들면 연관 관계의 주인을 정해야 한다.
  • 연관 관계의 주인은 테이블에 외래키가 있는 곳에서 정해야 한다.
class Member{
	...
    
    @OneToOne(mappedBy="member") // Member 엔터티는 mappedBy를 통해 주인이 아님을 설정 
    private Card card; 
}

주요 특징

  • 연관 관계의 주인만이 DB 연관 관계와 매핑 및 외래 키 관리
  • 주인이 아닌 반대편은 읽기만 가능 및 외래 키 변경 불가
  • 항상 "다[N]"쪽이 주인이다.
  • @ManyToOne은 항상 연관 관계의 주인이 됨, mappedBy 속성이 없다

예시

One-to-One 단방향

  • 회원은 카드 하나만 소유할 수 있으며 카드는 여러 사람에 의해 공유될 수 없다.
  • 카드 조회를 하면 소유자는 알 수 있으나 소유자를 조회하면 어떤 카드를 소지하는지 모른다.

Member 클래스 구현

@Getter // Lombok 
@Setter // Lombok 
@Entity
@Table(name = "members")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    
    @Temporal(TemporalType.Date)
    private Date birthDate;
    
    public Member(String name, String emial, Date birthDate){
        this.name = name;
        this.email = email;
        this.birthDate = birthDate;
    }
}

Card 클래스 구현

@Getter // Lombok 
@Setter // Lombok 
@Entity
@Table(name = "cards")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Temporal(TemporalType.DATE)
    private Date expDate;
    private String type;
    
    @OneToOne
    @JoinColumn(name = "members_id")
    private Member member;
    
    public Card(String type, Date expDate){
        this.type = type;
        this.expDate = expDate;
    }
}

연관 설정 코드

Calendar cal1 = Calendar.getInstance();
cal1.set(1999,1,1);
Date dob = cal1.getTime();
// Member 설정 (이름,이메일,생년월일)
Member m1 = new Member("velog","[email protected]",dob);
// Member 테이블에 저장 
memberRepository.save(m1); 

Calendar cal2 = Calendar.getInstance();
cal2.set(2002,12,31);
Date exd = cal2.getTime();
// Card 설정 (카드타입,카드유효날짜)
Card card1 = new Card("VELOG DAY",exd);
// Card의 Member 설정 
card1.setMember(m1);
// Card 테이블에 저장 
cardRepository.save(card1);

One-to-One 양방향

  • 회원은 카드 하나만 소유할 수 있으며 카드는 여러 사람에 의해 공유될 수 없다.
  • 카드 조회를 하면 소유자를 알 수 있고 소유자를 조회하면 어떤 카드를 소지하는지 알 수 있다.

Member 클래스 구현

@Getter // Lombok 
@Setter // Lombok 
@Entity
@Table(name = "members")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    
    @Temporal(TemporalType.Date)
    private Date birthDate;
     
    @OneToOne(mappedBy = "member", cascade = CascadeType.ALL)
    private Card card;
}

Card 클래스 구현 (주인)

@Getter // Lombok 
@Setter // Lombok 
@Entity
@Table(name = "cards")
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Temporal(TemporalType.DATE)
    private Date expDate;
    private String type;
    
    @OneToOne
    @JoinColumn(name = "members_id") // 외래키
    private Member member;
    
    public Card(String type, Date expDate){
        this.type = type;
        this.expDate = expDate;
    }
}

연관 설정 코드

Calendar cal1 = Calendar.getInstance();
cal1.set(1999,1,1);
Date dob = cal1.getTime();
// Member 설정 (이름,이메일,생년월일)
Member m1 = new Member("velog","[email protected]",dob);

Calendar cal2 = Calendar.getInstance();
cal2.set(2002,12,31);
Date exd = cal2.getTime();
// Card 설정 (카드타입,카드유효날짜)
Card card1 = new Card("VELOG DAY",exd);
// Card의 Member 설정 
card1.setMember(m1);
// Member의 Card 설정 
m1.setCard(card1);
// Member 테이블에 저장 
memberRepository.save(m1); 

Optional<Member> m = memberRepository.findById(1L);
m.ifPresent(s->System.out.println(s.getCard().getType());

참고 https://ultrakain.gitbooks.io/jpa/content/chapter5/chapter5.html

좋은 웹페이지 즐겨찾기