JPA에서 관계 유형별로 엔티티를 설정하는 방법을 정리해보자.
1. 다대일 (단방향)
-> 다쪽에 @ManyToOne 으로 설정
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | @Entity @Table(name = "student") @Data @NoArgsConstructor @AllArgsConstructor public class Student { @Id @Column(name = "STUDENT_ID") private String id; @Column(name = "name") private String name; @ManyToOne @JoinColumn(name = "CLASSES_ID") private Classes classes; public void setClasses(Classes classes) { // 먼저 지워준다. classes.getStudents().remove(this); // 그리고 반을 바꾸고 학생추가 this.classes = classes; classes.getStudents().add(this); } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Table(name = "classes") @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Classes { @Id @Column(name = "CLASSES_ID") private String id; @Column(name = "name") private String name; } | cs |
2. 다대일 양방향
-> 다쪽에 @ManyToOne, 일쪽에 @OneToMany를 지정해서 사용
-> 다쪽인 Student에서 외래키를 가지고 있으므로 직접 조작할 수 있고 반대쪽은 조회만 가능
-> 이전시간에 정리한거 처럼 setClasses(), addStudent()등에 메서드에 빈곳이 없도록 해야한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @Entity @Table(name = "student") @Data @NoArgsConstructor @AllArgsConstructor public class Student { @Id @Column(name = "STUDENT_ID") private String id; @Column(name = "name") private String name; @ManyToOne @JoinColumn(name = "CLASSES_ID") private Classes classes; public void setClasses(Classes classes) { // 먼저 지워준다. classes.getStudents().remove(this); // 그리고 반을 바꾸고 학생추가 this.classes = classes; classes.getStudents().add(this); } } @Table(name = "classes") @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Classes { @Id @Column(name = "CLASSES_ID") private String id; @Column(name = "name") private String name; @OneToMany(mappedBy = "classes") private List<Student> students; } | cs |
3. 일대다 (단방향)
-> 일대다에서 외래키가 다쪽에 존재
-> 다대일 단방향에서 일쪽에 @JoinColumn(name = "CLASSES_ID")가 추가된 형태
-> 일대다보다 될 수 있으면 다대일을 사용하자.
1 2 3 4 | @JoinColumn(name = "CLASSES_ID") @OneToMany(mappedBy = "classes") private List<Student> students; | cs |
4. 일대다 (양방향)
-> 일대다 매핑은 존재하지 않고 다대일 양방향으로 사용해야한다.
5. 일대일
-> 양쪽이 서로 하나의 관계만 가지는 것.
-> 양쪽 테이블 모두 외래키를 가질 수 있다.
-> @OneToOne으로 매핑하고 주인이 될 엔티티에 @JoinColumn을 사용하고, 나머지 엔티티에는 mappedBy 옵션을 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | @Entity @Table(name = "student") @Data @NoArgsConstructor @AllArgsConstructor public class Student { @Id @Column(name = "STUDENT_ID") private String id; @Column(name = "name") private String name; @ManyToOne @JoinColumn(name = "CLASSES_ID") private Classes classes; @OneToOne @JoinColumn(name = "LOCKER_ID") private Locker locker; public void setClasses(Classes classes) { // 먼저 지워준다. classes.getStudents().remove(this); // 그리고 반을 바꾸고 학생추가 this.classes = classes; classes.getStudents().add(this); } } @Table(name = "classes") @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Locker { @Id @Column(name = "LOCKER_ID") private String id; @Column(name = "location") private String location; @OneToOne(mappedBy = "locker") private Student student; } | cs |
6. 다대다
-> 데이터베이스에서 사용하지 않는 다대다를 사용하지 말고 중간에 중점을 두어 다대일로 구별하여 처리한다.
-> 예를 들어 학생과 책의 다대다 관계를 지칭한다 했을 때 중간에서 학생과 책의 관계를 담당하는 엔티티 StudentBook이 있다고 가정해보자.
-> Student에는 관계 테이블에서 사용될 키가 보함된 @OneToMany(mappedBy = "student")를 설정한다.
-> 관계 엔티티 에는 키를 관리하는 별도의 객체를 만들어서 @IdClass(StudentBookId.class)를 설정해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | @Entity @Table(name = "student") @Data @NoArgsConstructor @AllArgsConstructor public class Student { @Id @Column(name = "STUDENT_ID") private String id; @Column(name = "name") private String name; // 다대일 @ManyToOne @JoinColumn(name = "CLASSES_ID") private Classes classes; // 일대일 @OneToOne @JoinColumn(name = "LOCKER_ID") private Locker locker; // 다대다(중간에 관계테이블 있는경우) @OneToMany(mappedBy = "student") private List<Book> books; public void setClasses(Classes classes) { // 먼저 지워준다. classes.getStudents().remove(this); // 그리고 반을 바꾸고 학생추가 this.classes = classes; classes.getStudents().add(this); } } @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Book { @Id @Column(name = "PRODUCT_ID") private String id; private String name; } @Entity @IdClass(StudentBookId.class) public class StudentBook { @Id @ManyToOne @JoinColumn(name = "STUDENT_ID") private Student student; @Id @ManyToOne @JoinColumn(name = "BOOK_ID") private Book book; } @EqualsAndHashCode public class StudentBookId implements Serializable { private String student; private String book; } | cs |
'web > JPA' 카테고리의 다른 글
@MappedSuperclass를 이용한 부모 매핑정보 사용하기 (1) | 2018.11.03 |
---|---|
JPA 상속관계 매핑 전략 (0) | 2018.10.31 |
연관관계 매핑 (다대일 - 양방향) (0) | 2018.10.26 |
연관관계 매핑 - 다대일 매핑 (단반향) (0) | 2018.10.23 |
JPA 매핑 어노테이션 - DDL 2 (0) | 2018.10.13 |