2011-11-19 42 views
7

Tôi gặp sự cố khi hiểu sự khác biệt giữa @OneToMany@ManyToMany. Khi tôi sử dụng @OneToMany nó mặc định để tạo ra một JoinTable và nếu bạn thêm thuộc tính mappedBy bạn sẽ có mối quan hệ hai chiều giữa hai thực thể.Sự khác biệt giữa việc sử dụng @OneToMany và @ManyToMany

Tôi có một số Question có thể thuộc về nhiều Categories và một Category có thể thuộc về nhiều Questions. Tôi không hiểu nếu tôi nên sử dụng @ManyToMany hoặc @OneToMany bởi vì đối với tôi nó có vẻ giống hệt nhau, nhưng có lẽ là không.

Ai đó có thể giải thích nó?

Trả lời

15

Vâng, sự khác biệt nằm trong thiết kế mà bạn đang cố gắng phản ánh việc sử dụng các đối tượng.

Trong trường hợp của bạn, mỗi Question có thể được chỉ định cho nhiều Categories - vì vậy đó là dấu hiệu của mối quan hệ @*ToMany. Bây giờ bạn phải quyết định nếu:

  • mỗi Category có thể chỉ có một Question gán cho nó (nó sẽ gây ra một độc đáo chế có nghĩa là không khác loại có thể tham khảo các câu hỏi tương tự) - sẽ này là mối quan hệ @OneToMany,
  • mỗi Category có thể có nhiều số Questions được gán cho nó (sẽ không có ràng buộc duy nhất trong bảng Category) - đây sẽ là mối quan hệ @ManyToMany.

@OneToMany (Câu hỏi -> Danh mục)

Mối quan hệ này có thể được đại diện bởi tham gia bảng chỉ khi bạn rõ ràng xác định nên sử dụng @JoinTable hoặc khi nó là một một chiều mối quan hệ, trong đó phía sở hữu là mặt 'Một' (nghĩa là trong thực thể Question bạn có một bộ sưu tập là Categories, nhưng trong số Categories bạn không có bất kỳ tham chiếu nào đến số Question).

Nếu bạn nghĩ về nó, có vẻ khá hợp lý khi bàn nối được sử dụng. Không có cách nào khác DBMS có thể lưu kết nối giữa một hàng trong bảng Question có nhiều hàng trong bảng Categories.

Tuy nhiên, nếu bạn muốn mô hình hóa mối quan hệ hai chiều, bạn cần xác định rằng Category ('Nhiều' bên) là bên sở hữu của mối quan hệ.Trong trường hợp này DBMS có thể tạo cột nối với khóa ngoài trong bảng Category vì mỗi hàng Category có thể được kết nối chỉ với một Question. Bằng cách này, bạn không có bất kỳ bảng tham gia nào nhưng các khóa ngoại đơn giản (vẫn như được chỉ ra ở đầu, bạn có thể buộc tạo bảng kết nối bằng cách sử dụng @JoinTable).

@ManyToMany

Mối quan hệ này phải được thể hiện dưới dạng một bảng tham gia. Về cơ bản, nó hoạt động rất giống với mối quan hệ @OneToMany một chiều, nhưng trong trường hợp này, bạn có thể có nhiều hàng từ Question được kết hợp với nhiều hàng từ Categories.

+0

Giải thích tuyệt vời. Nên có nhiều upvotes hơn. – LppEdd

0

Các mối quan hệ @ManyToMany có các khóa ngoại lai tham chiếu lẫn nhau ở cả hai bên của mối quan hệ. Đôi khi, mối quan hệ này được trung gian bởi một bảng liền kề.

@OneToMany mối quan hệ có khóa ngoại ở bên "một" và không ở phía "nhiều". Trong mối quan hệ @OneToMany, một đối tượng là "cha mẹ" và một là "con". Cha mẹ kiểm soát sự tồn tại của đứa trẻ.

Hãy nhớ rằng mối quan hệ hai chiều @ManyToMany không cần đối xứng!

0

Trong câu hỏi & Trường hợp danh mục, bạn nên sử dụng mối quan hệ @ManyToMany. @ManyToMany về cơ bản có nghĩa là "một Câu hỏi có thể thuộc về nhiều Danh mục cùng một lúc" và "Danh mục có thể chứa nhiều Câu hỏi cùng một lúc". Một bảng mới sẽ tự động được tạo để lưu trữ ánh xạ. Mã của bạn sẽ trông như thế này:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToMany 
    private List<Category> categories; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @ManyToMany 
    private List<Question> questions; 
    ... 
} 

Nếu bạn sử dụng mối quan hệ @OneToMany cho câu hỏi và hạng mục của bạn (giả sử loại trên Một bên và câu hỏi trên khác), điều này có nghĩa rằng "câu hỏi chỉ có thể thuộc về một Danh mục "và" Danh mục có thể chứa nhiều Câu hỏi cùng một lúc ". Không cần có bảng mới để lưu trữ ánh xạ. Thay vào đó, một trường mới sẽ tự động được tạo ở bên Nhiều để ghi lại ID của Một bên. Mã của bạn sẽ trông giống như sau:

@Entity 
public class Question implements Serializable { 
    ... 
    @ManyToOne 
    private Category theCategory; 
    ... 
} 

@Entity 
public class Category implements Serializable { 
    ... 
    @OneToMany(mappedBy="theCategory") 
    private List<Question> questions; 
    ... 
} 
Các vấn đề liên quan