
단방향 : 두 객체 중 하나의 객체만 참조용 필드를 참조
양방향 : 두 객체 모두 각각 참조용 필드를 참조한 것. 즉, 서로 단방향 관계를 이루고 있음
데이터베이스는 단방향과 양방향을 구분할 필요가 없지만, 다른 객체를 참조하기 위해서는 참조용 필드가 필요하다.
→ 참조가 필요한 부분만 참조를 해준다. 굳이 양방향일 필요는 없다. 복잡성만 증가한다.
연관 관계의 주체는 외래키를 관리할 수 있고, 주체가 아닌 쪽은 읽기만 가능하다.
mappedBy를 사용하여 주체 지정@ManyToOne (N:1) > 주체는 N쪽하나의 게시판은 여러 게시글을 가지고 있다.
→ post가 주체
@Entity(name="board")
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
}
@Entity(name="post") // entity이름과 테이블 이름이 같다면 name 옵션 생략가능
public class Post {
@Id
@GeneratedValue
@Column(name = "POST_ID")
private Long id;
private String title;
@ManyToOne
@JoinColumn(name = "BOARD_ID") // 외래키 이름을 지정해주는 역할. 생략 가능함
private Board board;
}
다대일 관계를 매핑할 때는 @JoinColumn을 생략할 수 있다.
필드명 + _ + 참조하는 테이블의 컬럼명으로 join을 진행한다.
@Entity(name="board")
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@OneToMany(mappedBy = "board") //entity이름이 들어가야함
List<Post> posts = new ArrayList<>();
}
@Entity(name="post") // entity이름과 테이블 이름이 같다면 name 옵션 생략가능
public class Post {
@Id
@GeneratedValue
@Column(name = "POST_ID")
private Long id;
private String title;
@ManyToOne
private Board board;
}
@OneToMany(1:N) > 주체는 1쪽❗ 실무에서 일대다관계는 잘 사용하지 않는다.
보통 데이터베이스 입장에서는 무조건 N쪽에서 외래키를 관리한다.
그러나 일대다관계는 일(1)쪽에서 외래키를 관리하는 경우이다.
그렇기 때문에 insert 한번으로 처리 가능한 작업에 update가 추가로 발생한다.
→ board가 주체
@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@OneToMany
@JoinColumn(name = "BOARD_ID")// 일대다 관계에서는 JoinColumn 생략불가능
List<Post> posts = new ArrayList<>();
}
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "POST_ID")
private Long id;
private String title;
}
일대다 단방향 관계를 매핑할 때는 @JoinColumn을 생략할 수 없다.
생략한다면 JPA는 연결 테이블을 중간에 생성하여 조인을 한다.
//저장
Post post1 = new Post("post1");
entityManager.persist(post1);
Board board1 = new Board("board1");
board1.getPosts().add(post1);
entityManager.persist(board1);
이때 생성되는 SQL을 확인하면, post1과 board1에서 insert가 발생하고, post1에 board1의 id를 저장하는 과정에서 update 쿼리가 날아간다.
추가 쿼리가 생성되는 것도 문제가 되지만, 구조적으로도 엔티티를 매핑한 테이블이 아닌 다른 테이블의 외래키를 관리하는 것은 더 복잡하다.
거의 사용하지 않음. 양방향 관계가 필요하다면 다대일 관계를 사용하자
@OneToOne(1:1)일대일 관계는 주테이블이나 대상 테이블 중에 외래키를 넣을 테이블을 선택할 수 있다.
외래키에 데이터베이스 unique제약조건이 추가되어야 일대일관계가 된다.
다대일 단방향 관계 매핑과 거의 유사함
다대일 양방향 관계 매핑처럼 외래키가 있는 곳이 연관 관계의 주인이다.
지원하지 않음
주 테이블 외래키 양방향을 반대로 뒤집어 매핑한다고 생각하면 된다.
→ JPA매핑이 편리하려면 주테이블에 외래키가 있는 것이 좋다. 주테이블은 많이 접근하는 테이블로 설정하자.
장점 > 주테이블만 조회해도 대상 테이블에 데이터가 있는지 확인가능하다.
단점 > 값이 없으면 외래키에 null값을 허용해야한다. db 입장에서는 좋지않다.
@ManyToMany(N:M)사용을 자제하자. 불필요한 쿼리가 많이 생길 수 있다.
고려할 부분
외래키이 주인이 아닌 쪽에 데이터를 안넣어 준다면 DB에서 문제가 발생하지 않지만
데이터 조회를 하지 못하는 경우가 발생한다.