이것은 매우 일반적인 질문이므로이 답변은 내 블로그에 쓴 이 기사를 기반으로 합니다 .
일대 다
일대 다 테이블 관계는 다음과 같습니다.
관계형 데이터베이스 시스템에서 일대 다 테이블 관계 는 부모 테이블 행 Foreign Key
을 참조하는 자식 의 열을 기준으로 두 테이블을 연결 Primary Key
합니다.
위 표 다이어그램에서 post_id
에서 열 post_comment
테이블이 갖는 Foreign Key
와 관계 post
테이블 아이디 Primary Key
칼럼 :
ALTER TABLE
post_comment
ADD CONSTRAINT
fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
@ManyToOne 주석
일대 다 테이블 관계를 매핑하는 가장 좋은 방법은 @ManyToOne
주석 을 사용하는 것 입니다.
이 경우 자식 엔터티 는 주석을 사용하여 외래 키 열을 PostComment
매핑합니다 .post_id
@ManyToOne
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
}
JPA @OneToMany
주석 사용
@OneToMany
어노테이션 사용 옵션 이 있다고해서 이것이 일대 다 데이터베이스 관계 마다 기본 옵션이어야한다는 의미는 아닙니다 . 컬렉션의 문제점은 하위 레코드 수가 다소 제한된 경우에만 사용할 수 있다는 것입니다.
@OneToMany
연결 을 매핑하는 가장 좋은 방법 은 @ManyToOne
모든 엔터티 상태 변경 사항을 전파 하는 측면에 의존하는 것입니다 .
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
}
부모 엔터티 는 양방향 연결의 양쪽을 동기화하는 데 사용되는 Post
두 가지 유틸리티 방법 (예 : addComment
및 removeComment
)을 제공합니다. 양방향 연관 작업을 수행 할 때마다 항상 이러한 방법을 제공해야합니다. 그렇지 않으면 매우 미묘한 상태 전파 문제가 발생할 수 있습니다 .
단방향 @OneToMany
연결은 @ManyToOne
양방향 @OneToMany
연결을 사용 하는 것보다 비효율적이므로 피해야합니다 .
@OneToMany
JPA 및 Hibernate와의 관계 를 맵핑하는 가장 좋은 방법에 대한 자세한 내용은 이 기사를 확인 하십시오 .
1-1
일대일 테이블 관계는 다음과 같습니다.
관계형 데이터베이스 시스템에서 일대일 테이블 관계 는 상위 테이블 행 Primary Key
의 Foreign Key
참조 를 나타내는 하위 의 열을 기반으로 두 테이블을 연결 Primary Key
합니다.
따라서 자식 테이블 Primary Key
과 부모 테이블을 공유한다고 말할 수 있습니다 .
위 표 다이어그램에서 id
에서 열 post_details
테이블도 가지고 Foreign Key
와 관계 post
테이블 id
Primary Key
칼럼 :
ALTER TABLE
post_details
ADD CONSTRAINT
fk_post_details_id
FOREIGN KEY (id) REFERENCES post
주석 @OneToOne
과 함께 JPA 사용@MapsId
@OneToOne
관계 를 매핑하는 가장 좋은 방법 은을 사용하는 것 @MapsId
입니다. 이런 식으로 엔터티 식별자 PostDetails
를 사용하여 Post
엔터티 를 항상 가져올 수 있으므로 양방향 연결조차 필요하지 않습니다 .
매핑은 다음과 같습니다.
[code language = "java"] @Entity (name = "PostDetails") @Table (name = "post_details") 공개 클래스 PostDetails {
@Id
private Long id;
@Column(name = "created_on")
private Date createdOn;
@Column(name = "created_by")
private String createdBy;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "id")
private Post post;
public PostDetails() {}
public PostDetails(String createdBy) {
createdOn = new Date();
this.createdBy = createdBy;
}
//Getters and setters omitted for brevity
} [/ 코드]
이런 식 id
으로이 속성은 기본 키와 외래 키의 역할을합니다. 당신은 알 수 없을 것이다 @Id
열이 더 이상 사용 @GeneratedValue
식별자가의 식별자로 채워되기 때문에 주석을 post
연결.
@OneToOne
JPA 및 Hibernate와의 관계 를 맵핑하는 가장 좋은 방법에 대한 자세한 내용은 이 기사를 확인 하십시오 .
다 대다
다 대다 테이블 관계는 다음과 같습니다.
관계형 데이터베이스 시스템에서 다 대다 테이블 관계는 두 개의 상위 테이블의 Foreign Key
열을 참조하는 두 개의 열 을 포함하는 하위 테이블을 통해 두 개의 상위 테이블을 연결합니다 Primary Key
.
위의 테이블 다이어그램에서 테이블의 post_id
열 은 테이블 ID 열과 관계 post_tag
가 있습니다 .Foreign Key
post
Primary Key
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post
그리고 테이블 의 tag_id
열 은 테이블 ID 열과 관계가 있습니다 .post_tag
Foreign Key
tag
Primary Key
ALTER TABLE
post_tag
ADD CONSTRAINT
fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag
JPA @ManyToMany
매핑 사용
다음은 many-to-many
JPA 및 Hibernate와 테이블 관계를 맵핑하는 방법입니다 .
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private Set<Tag> tags = new HashSet<>();
//Getters and setters ommitted for brevity
public void addTag(Tag tag) {
tags.add(tag);
tag.getPosts().add(this);
}
public void removeTag(Tag tag) {
tags.remove(tag);
tag.getPosts().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Post)) return false;
return id != null && id.equals(((Post) o).getId());
}
@Override
public int hashCode() {
return 31;
}
}
@Entity(name = "Tag")
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String name;
@ManyToMany(mappedBy = "tags")
private Set<Post> posts = new HashSet<>();
//Getters and setters ommitted for brevity
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Tag tag = (Tag) o;
return Objects.equals(name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
- 엔터티 의
tags
연결 Post
은 PERSIST
및 MERGE
캐스케이드 유형 만 정의합니다 . 설명한 바와 같이 ,이 기사 는 REMOVE
엔티티의 상태 천이는 A에 대한 어떠한 의미하지 않는다 @ManyToMany
궁극적 연관 양쪽 닦아 것이다 연쇄 삭제를 실행할 수 있기 때문에 JPA 협회.
- 이 기사 에서 설명한대로 양방향 연관을 사용하는 경우 추가 / 제거 유틸리티 메소드는 필수이므로 연관의 양쪽이 동기화되었는지 확인할 수 있습니다.
Post
는 고유 한 비즈니스 키가 부족하기 때문에 기업은 평등에 대한 개체 식별자를 사용합니다. 이 기사 에서 설명한대로 모든 엔티티 상태 전이에서 일관성을 유지하는 한 엔티티 식별자를 동등하게 사용할 수 있습니다 .
Tag
기업은 최대 절전 모드 별의 표시하는 고유 한 비즈니스 키가 @NaturalId
주석을. 이 경우 고유 한 비즈니스 키가 동등성 검사에 가장 적합한 후보입니다 .
mappedBy
의 속성 posts
에 연관 Tag
이 양방향 관계 엔티티 마크 Post
엔티티가 관계를 소유하고있다. 한 쪽만 관계를 소유 할 수 있으므로 변경이이 특정 쪽에서 데이터베이스로만 전파되기 때문에이 작업이 필요합니다.
- 는
Set
사용 a 같이 선호된다 List
으로 @ManyToMany
덜 효율적이다.
@ManyToMany
JPA 및 Hibernate와의 관계 를 맵핑하는 가장 좋은 방법에 대한 자세한 내용은 이 기사를 확인 하십시오 .