[JPA 활용 1] Entity 연관 관계 매핑

홍정완·2022년 4월 9일
0

JPA

목록 보기
2/38
post-thumbnail

관계형 데이터베이스는 테이블 간 foreign key로 연관관계를 맺고 JOIN을 통해 테이블을 조회한다.


예를 들어 Parking 테이블과 Charge 테이블의 연관관계를 M:1 관계라 하자.

그렇다면 기본적으로 외래 키는 M 쪽인 Parking 테이블에 존재하고,
Parking JOIN Charge, Charge JOIN Parking 양쪽 모두에서 조회가 가능하다.




객체의 경우, Parking에 Charge 멤버 변수를 두어 관계를 맺는다.
Parking -> Charge 조회는 가능하지만, Charge -> Parking는 조회할 수 없다. 이러한 관계를 단방향 관계라 부른다.



그렇다면 JPA를 통해 연관관계가 어떻게 매핑되는지 자세히 알아보자.



다대일 (M : 1) 단방향 관계


@Entity
public class Parking {

    @Id
    @GeneratedValue
    private Long id;
    
    private String ParkingName;
    
    @ManyToOne
    @JoinColumn(name="charge_id")
    private Charge charge;
    
}


@Entity
public class Charge {

    @Id
    @GeneratedValue
    private Long id;
    
    private String chargeName;
    
}

위 코드는 Parking 테이블에 외래 키인 charge_id가 생성되고, 단방향이기 때문에 Charge 엔티티에서는 Parking을 알 수 없다.



  • @ManyToOne : M:1 관계를 표현하는 어노테이션

    • @ManyToOne이 붙은 엔티티가 M이고 반대 엔티티가 1일 때 붙인다.

  • @JoinColumn(name="") : 외래 키를 정의하는 어노테이션



다대일 (M : 1) 양방향 관계


양방향 매핑 코드를 봐보자.


@Entity
public class Parking {

    @Id
    @GeneratedValue
    private Long id;
    
    private String ParkingName;
    
    @ManyToOne
    @JoinColumn(name="charge_id")
    private Charge charge;
    
}


@Entity
public class Charge {

    @Id
    @GeneratedValue
    private Long id;
    
    private String chargeName;
    
    //양방향 매핑을 위한 추가
    @OneToMany(mappedBy = "charge")
    private List<Parking> parking = new ArrayList<>();
    
}



Charge에 Parking를 저장할 필드가 생성된 것을 볼 수 있고, @OneToMany 어노테이션이 사용됐다.
속성 mapppedBy는 양방향 매핑일 때 사용한다.



  • JPA는 두 개의 연관관계 중 하나를 고르게 하기 위해 mappedBy를 설정

  • mappedBy가 없는 엔티티가 연관관계의 주인

    • mappedBy가 없는 Parking 엔티티에 외래 키가 생성



일대다(1:M) 단방향 관계


일반적으로 일대다 단방향 관계 매핑은 권장되지 않고, 다대일 단방향으로 관계를 맺는 것이 좋다.



일대다(1:M) 양방향 관계


일대다 양방향 관계는 존재하지 않는다.

  • 일대다 양방향 == 다대일 양방향
    • 같은 말이다.



일대일(1:1) 단방향 관계


  • 양쪽이 서로 하나의 관계만 가진다.

  • 외래 키가 어디에 있든 상관이 없다.


@Entity
public class Parking {

    @Id
    @GeneratedValue
    private Long id;
    
    private String ParkingName;
       
}


@Entity
public class Charge {

    @Id
    @GeneratedValue
    private Long id;
    
    private String chargeName;
    
    @OneToOne
    @JoinColumn(name = "parking_id")
    private Parking parking
    
}



일대일(1:1) 양방향 관계


@Entity
public class Parking {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String ParkingName;
    
    @OneToOne(mappedBy = "parking")
    private Charge charge;
    
}


@Entity
public class Charge {

    @Id
    @GeneratedValue
    private Long id;
    
    private String chargeName;
    
    
    @OneToOne
    @JoinColumn(name = "parking_id") 
    // parking을 연관관계 주인으로 하고 싶다면 mappedBy, @joinColumn의 위치를 서로 바꿔준다.
    private Parking parking;
    
}



다대다 (M:M) 관계


두 테이블 사이에 중간 테이블을 두어 관계를 풀어줘야 하는데 실무에서 한계가 존재하기 때문에 지양하자.



이유


  • 중간 테이블을 묵시적으로 생성해 주기 때문에 복잡한 조인 쿼리가 발생

  • 중간 테이블에 필요한 추가 컬럼을 사용할 수 없다.

    • 추가된 컬럼에 대해 매핑이 되지 않기 때문이다.



자동 생성 전략


IDENTITY


@GeneratedValue(strategy = GenerationType.IDENTITY)


  • 기본 키 생성을 데이터베이스에 위임

  • 즉, id 값을 null로 하면 DB가 알아서 AUTO_INCREMENT

    • Ex) MySQL, PostgreSQL, SQL Server DB2 등



profile
습관이 전부다.

0개의 댓글