관계형 데이터베이스의 연관관계는 외래키(FK)를 참조하여 다른 테이블과 맺습니다. 그렇다면 객체는 연관관계를 어떻게 맺으면 좋을까요?
객체는 연관관계를 맺을 다른 객체를 참조(Reference) 하여 연관관계를 맺습니다.
방향성 또한 테이블은 양방향 연관관계를 가지고 객체는 단방향 연관관계를 가지는 것이 큰 차이점입니다.
이 불편한 패러다임 불일치를 해소시켜주는 것이 Spring JPA 입니다. JPA를 사용하여 연관관계를 맺어보겠습니다.
🔴 연관관계 맺어보기
먼저 테이블에서는 외래키(FK)를 참조하여 다른 테이블과 연관관계를 맺는건 알고 계실 겁니다.
테이블처럼 연관관계를 맺어보면 방문기록 객체에 유저 객체의 PK값을 참조하려면 아래 코드처럼 코드를 작성해야합니다.
@Entity
public class Visits extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long visitsId;
private Long usersId;
}
@Entity
public class Users extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "users_id")
private Long id;
}
테이블처럼 연관관계를 맺어봤지만 객체에서는 서로 연관관계가 맺어진 것이 아닙니다.
객체에서는 연관관계를 맺을 다른 객체를 참조(Referecne) 하여 관계를 맺어야 합니다.
아래 코드처럼 유저 객체를 참조해야하고 어노테이션 @ManyToOne 을 붙여주어 N : 1 의 단방향 연관관계를 맺어줍니다.
다음으로 조인할 컬럼을 지정해줍니다. 아래 코드에서는 유저와 조인을 해야하므로 유저의 id 값으로 지정하였습니다.
@Entity
public class Visits extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long visitsId;
@ManyToOne
@JoinColumn(name = "users_id")
private Users users;
}
위의 코드는 현재 단방향 연관관계를 맺어놓은 상태입니다.
단방향 연관관계여도 참조한 객체를 통하여 조인이 가능하므로 단방향 연관관계를 맺어놓고 양방향 연관관계가 필요하면 객체를 추가해주고 @OneToMany 어노테이션을 붙여 mappedBy 속성으로 주인을 지정해줍니다.
🔴 연관관계의 주인은?
연관관계의 주인을 어떤 객체에 맡겨야 하나 생각이 듭니다. 유저 객체와 방문기록 객체 둘다 연관관계의 주인을 주면 좋을까요? 연관관계의 주인은 둘중 하나만 해야합니다. 누구에게 주인을 줘야할까 생각이 들겁니다. 주인은 외래키 즉, 참조한 객체를 가지고 있는 객체에 연관관계 주인을 설정해야합니다.
@Entity
public class Users extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "users_id")
private Long id;
@OneToMany(mappedBy = "users")
private List<Visits> visits;
}
@Entity
public class Visits extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long visitsId;
@ManyToOne
@JoinColumn(name = "users_id")
private Users users;
}
보통 N : 1 의 연관관계를 가질 때 N 쪽을 연관관계의 주인으로 설정합니다.
'JPA' 카테고리의 다른 글
[Jpa] Deprecated 된 getById() 대안 getReferenceById() (0) | 2022.08.02 |
---|---|
[Jpa] Dirty Checking (0) | 2022.07.19 |
[Jpa] Projections (0) | 2022.07.18 |
[Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까? (1) | 2022.05.18 |
[Spring JPA] CASCADE 는 무엇일까? (0) | 2022.05.15 |
[Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까? (0) | 2022.05.15 |
[Spring JPA] 프록시 객체는 어떻게 동작할까? (0) | 2022.05.12 |
[Spring JPA] 객체지향의 상속관계 매핑은 어떤 전략을 사용할까? (0) | 2022.05.12 |