상세 컨텐츠

본문 제목

[SPRING] JPA 프로그래밍 기본 | 연관관계

JAVA/기본 & 강의복습

by ranlan 2021. 3. 9. 22:04

본문

728x90

객체와 테이블 매핑

@Entity(name = "entity_name") 
@Table(name = "table_name")
public class Member {

    @Id
    @GeneratdValue(strategy = GenerationType.IDENTITY)
    private Long id; 
    
    @Column
    private String memberId;
    private String memberNm;
    private String memberPw;

}

 

기본키

- @Id : 직접할당

- @GeneratedValue : 아이디 자동생성

GenerationType.XX  
IDENTITY 데이터베이스에 위임
MySQL의 AUTO_INCREMENT
TABLE 키 생성 전용 테이블을 만들어 시퀀스를 흉내내는 전략
모든 DB에 적용 가능하나 성능이 떨어짐
@TableGenerator 필요
SEQUENCE 오라클, PostgreSQL, H2 등
AUTO 하이버네이트에 따라 자동 지정, 기본값

 

컬럼

- @Column : 컬럼 매핑

속성 설명 기본값
name 필드와 매핑할 테이블의 컬럼 이름
객체의 필드 이름
nsertable, updatable 등록, 변경 가능 여부 true 
nullabe(DDL) null값 허용 여부 true
columnDefinition(DDL) 데이터베이스 컬럼 정보 직접 부여ex) char(1) default 'Y'  
length(DDL) 문자 길이 제약조건, String 타입에만 사용 255
precision scale(DDL) BigDecimal(소수) 타입에 사용, BigInteger에도 사용 가능 percision=19, scale=2

 

- @Temporal : 날짜 타입 매핑

TemporalType.XX  
DATE 날짜
TIME 시간
TIMESTAMP 날짜와 시간

 

- @Enumerated : enum 타입 매핑

EnumType.XX  
 STRING enum 이름으로 저장
 ORDINAL enum 순서 번호로 저장 (권장하지 않음)

 

- @Lob : 데이터베이스 BLOB, CLOB 타입과 매핑

- @Transient : DB에 저장되지 않고 조회도 불가능한 속성으로 메모리상에서만 임시로 보관하고 싶을 때 사용  

 

 

테이블 연관관계

테이블 사이 관계는 조인과 외래키로 표현하지만 객체는 객체 사이 참조로 표현

테이블은 외래 키 하나로 두 테이블의 연관관계를 맺을 수 있으나 객체는 단방향 연결 두 번(두 번의 참조)를 통해 양방향 연관관계를 맺음

 

* 연관관계의 주인은 외래키가 있는 곳 (참조하는 곳)

 

주인 주인 반대편
참조하는 곳(외래키가 있는 곳) 참조되는 곳
읽고 쓰기 가능 읽기만 가능
@JoinColumn(name="상대 객체에서 참조하는 컬럼 명") @OneToMany(mappedBy="주인객체에서 매핑 객체 대상")

 

 

연관관계1) 일대일(OneToOne) 

그의 반대 관계도 일대일 관계

외래 키에 데이터베이스 유니크(UNI) 제약조건 추가

주 테이블이나 대상 테이블 중 외래키가 있는 곳 선택 가능 (외래 키가 있는 곳이 주인)

일대일 매핑

1) 대상 테이블에 외래 키가 있는 경우

   일대다 관계로 변경할 때(한 member가 여러 locker를 소지할 수 있다고 서비스를 변경할 때) 테이블 구조 유지 가능

   프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩

2) 주 테이블에 외래 키가 있는 경우

   주 테이블(Member)만 조회해도 대상 테이블(Locker)에 데이터가 있는 지 확인 가능

   값이 없을 때가 있을 수 있음으로 외래 키에 null 허용

 

주 테이블

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long memberId;

    @Column
    private String memberName;
    private int memberAge;

    @OneToOne
    @JoinColum(name = "lockerId") 
    private Locker locker;
}

Locker 객체의 lockerId 참조

 

대상테이블

@Entity
public class Locker {

    @Id @GeneratedValue
    private Long lockerId;


    @OneToOne(mappedBy = "locker") 
    private Member member;
}

Member객체(주 테이블)의 locker 속성과 매핑

 

 

연관관계2) 일대다(OneToMany) 

보통 자신이 매핑한 테이블의 외래 키를 관리하나, 이 경우 반대 테이블의 외래 키를 관리

ex) Team 객체(1) 에서 각 팀에 속한 members(다) 관리함 따라서 Team(1) 쪽이 연관관계의 주인 (외래키를 지녔기 때문)

 

엔티티가 관리하는 외래 키가 다른 테이블에 있어 연관관계 관리를 위해 추가 update 쿼리를 실행해야함

ex) Member 추가 시 Member 테이블 뿐 아니라 Team 객체의 members에도 추가해 주어야함

 

@JoinColumn을 꼭 사용해야 함

사용하지 않을 시 Jpa는 자동으로 두 연관관계를 관리하는 Join 테이블 전략 사용하여 매핑

 

* 일대다만 연결은 지양, 다대일 양방향 매핑 사용할 것

 

주인 객체

@Entity
public class Team {

    @Id
    @GeneratedValue
    private Long teamId;

    @Column
    private String teamName;

    @OneToMany
    @JoinColumn(name = "teamId")
    List<Member> members = new ArrayList<Member>();
}

주인 반대편 객체

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long memberId;

    @Column
    private String memberName;
    private int memberAge;
}

 

 

연관관계3) 다대일(ManyToOne) 

가장 많이 사용하는 연관관계로 주로 양쪽을 서로 참조하도록 개발 (양방향 매핑)

외래 키가 있는 쪽이 연관관계의 주인

 

주인 객체 (단방향시 주인만 존재)

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long memberId;

    @Column
    private String memberName;
    private int memberAge;

    @ManyToOne
    @JoinColum(name = "teamId")
    private Team team;
}

Member 테이블이 Team 테이블이 teamId 컬럼 참조

 

주인이 아닌 테이블(양방향)

@Entity
public class Team {

    @Id
    @GeneratedValue
    private Long teamId;

    @Column
    private String teamName;

    
    @OneToMany(mappedBy = "team")
    List<Member> members = new ArrayList<Member>();
}

Member 객체 내 team 속성과 매핑

 

 

연관관계4) 다대다(ManyToMany) 

실무에서 거의 사용하지 않음

728x90

관련글 더보기

댓글 영역