[JPA] JPA 연관관계 매핑

아는벌·2023년 3월 9일
0

web (2)

목록 보기
18/20

단방향 연관 관계

게시판과 회원은 단방향으로 게시판은 회원 참조
회원은 게시판에 대한 참조 정보를 가지지 않음

@Data
@Entity
public class Board {
    @Id
    @GeneratedValue
    private Integer seq;
    private String title;
//    private String writer;
    private String content;
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date createDate;
    private Integer cnt;

    // 연관관계 매핑
    @ManyToOne
    @JoinColumn(name = "MEMBER_ID")
    private Member member;
}

@ManyToOne

  • N:1 관계
  • N에 해당하는 참조변수에 설정함!
  • 속성
    • optional : 연관된 엔티티의 필수 여부
    • fetch : 글로벌 패치 전략 설정
      • EAGER : 연관 엔티티를 즉시 가져옴
      • Lazy : 연관 엔티티가 실제 사용될 때 가져옴
    • cascade : 영속성 전이 범위 설정, 연관 엔티티를 관리할 때 사용(등록/수정/삭제)

@JoinColumn

  • fk를 매핑할 때 사용
  • name 속성에 매핑할 fk 이름 지정
  • 생략 가능 -> '참조변수이름_기본키 칼럼 이름'으로 자동 설정됨

저장

    @Test
    public void manyToOneInsert(){
    	// member 
        Member member = new Member();
        member.setId("member1");
        member.setName("나다");
        member.setPassword("1212");
        member.setRole("User");
		// 저장
        memberRepository.save(member);

		// board 
        for(int i = 1; i <=3; i++){
            Board board = new Board();
            board.setMember(member);
            board.setTitle("게시글제목"+i);
            board.setContent("게시글 내용입니다"+i);
            board.setCreateDate(new Date());
            board.setCnt(0);
            // 저장
            boardRepository.save(board);
        }
    }

엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야함


실행 결과

조회

    @Test
    public void manyToOneSelect(){
        // 조회
        Board board = boardRepository.findById(3).get();

		// 결과 정보 출력
        System.out.println("[ "+board.getSeq()+" 번 게시물 정보 ]");
        System.out.println("제목 : "+ board.getTitle());
        System.out.println("내용 : "+ board.getContent());
        // board의 member 정보 출력
        System.out.println("작성자 : "+ board.getMember().getName());
        System.out.println("작성자 권한 : "+ board.getMember().getRole());
    }


@ManyToOne 어노테이션의 패치 속성의 기본은 EAGER으로 select 결과에 외부 조인(outer join)이 처리됨

    // 연관관계 매핑
    @ManyToOne
    @JoinColumn(name = "MEMBER_ID", nullable=false)
    private Member member;
  • 외부 조인보다 내부 조인의 성능이 더 좋음
  • @JoinColumn의 nullable 속성을 이용하면 외부 조인으로 처리되는 쿼리를 내부 조인으로 변경 가능

양방향 연관관계

  • 연관관계에 참여하는 엔티티가 서로에 대한 참조를 양쪽에서 가지는 것
  • 양방향 관계에서 매핑에 참여하는 참조 변수는 두 개인데 외래 키는 하나여서 차이 발생
  • 두 참조 변수 중 하나를 연관관계의 주인으로 지정
  • 연관관계의 주인만 DB 연관관계와 매핑/ 외래키 관리 가능
  • 주인이 아닌 쪽은 읽기만 가능(외래 키 변경 불가)
  • 주인이 아닌 곳의 입력된 값은 외래 키에 영향 X
  • 항상 다(N)쪽이 외래 키를 가짐

게시판 관점에서 멤버는 다대일 관계
멤버 관점에서 게시판은 일대다 관계 -> 일대다 관계는 List와 같은 컬렉션 사용해야함

@Data
@Entity
@ToString(exclude = "boardList")
public class Member {
    @Id
    private String id;
    private String password;
    private String name;
    private String role;

    @OneToMany(mappedBy = "member", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Board> boardList= new ArrayList<>();
}

@OneToMany

  • 일대다 관계
  • 속성
    - fetch - 연관된 엔티티의 조회 시점 결정(@OneToMany의 기본 설정: LAZY)
    - mappedBy - 주인이 아니면 mappedBy 속성을 사용해 속성 값으로 연관관계 주인 지정

cascade(영속성 전이)

  • 부모 엔티티의 상태 변화가 자식 엔티티에도 전이
    1) ALL - 모든 영속성 전이
    2) PERSIST - 엔티티가 저장될 때만 연쇄적으로 저장
    3) REMOVE
    4) MERGE
    5) REFERESH
    6) DETACH

순환 참조 처리

@ToString(exclude = "boardList")

  • 순환 참조 문제를 해결하기 위해 @ToString의 exclude 속성 사용
  • 연관관계에 참여하는 두 엔티티 중 한 곳에만 설정해도 됨

참고

https://ultrakain.gitbooks.io/jpa/content/chapter5/chapter5.html
https://hongchangsub.com/jpa-cascade-2/

0개의 댓글