hibernate多对多映射拆成2个一对多映射(注解)
hibernate的many to many確實很是方便我們處理實體和集合間的關(guān)系,并可以通過級聯(lián)的方法處理集合,但有的時候many to many不能滿足我們的需要,比如 用戶<--->選課,典型的多對多關(guān)系,一般情況下,會生成
course_user(course_id,user_id);
但用戶選課的時候最好加入審核功能,所以我們希望在中間自動生成的表中加入一個boolean字段,類似這種結(jié)構(gòu):
course_user(course_id,user_id,accessable);
這個時候我們可以把many to many拆分成2個many to one ,自己手動添加個中間表,這樣擴(kuò)展就好很多了。
代碼如下:
@Embeddable
public class CourseUserPK implements Serializable{
??? private static final long serialVersionUID = 1L;
??? private Course course;
??? private User user;
??? @ManyToOne
??? @JoinColumn(name = "course_id", nullable = false)
??? public Course getCourse() {
??????? return course;
??? }
??? public void setCourse(Course course) {
??????? this.course = course;
??? }
??? @ManyToOne
??? @JoinColumn(name = "user_id", nullable = false)
??? public User getUser() {
??????? return user;
??? }
??? public void setUser(User user) {
??????? this.user = user;
??? }
??? public boolean equals(Object object) {
??????? if (this == object)
??????????? return true;
??????? if (!(object instanceof CourseUserPK))
??????????? return false;
??????? final CourseUserPK other = (CourseUserPK) object;
??????? if (this.course != null && other.getCourse() != null) {
??????????? if(course.getId() == other.course.getId()) {
??????????????? if(user!=null&&other.getUser()!=null&&user.getId()==other.getUser().getId()) {
??????????????????? return true;
??????????????? } else {
??????????????????? return false;
??????????????? }
??????????? } else {
??????????????? return true;
??????????? }
??????? } else
??????????? return false;
??? }
??? public int hashCode() {
??????? return super.hashCode()+
??????????????? (course!=null?course.hashCode():0)+
??????????????? (user!=null?user.hashCode():0);
??? }
}
@Entity
@IdClass(CourseUserPK.class)
public class CourseTeacher {
??? private Course course;
??? private User user;
??? private Boolean accessable;//true user is in course, otherwise not
???
??? public CourseTeacher(Course course, User user, Boolean accessable) {
??????? this.course = course;
??????? this.user = user;
??????? this.accessable = accessable;
??? }
??? @Id
??? public Course getCourse() {
??????? return course;
??? }
??? public void setCourse(Course course) {
??????? this.course = course;
??? }
??? @Id
??? public User getUser() {
??????? return user;
??? }
??? public void setUser(User user) {
??????? this.user = user;
??? }
??? public Boolean getAccessable() {
??????? return accessable;
??? }
??? public void setAccessable(Boolean accessable) {
??????? this.accessable = accessable;
??? }
}
@Entity
@IdClass(CourseUserPK.class)
public class CourseStudent {
??? private Course course;
??? private User user;
??? private Boolean accessable;//true user is in course, otherwise not
???
???
??? public CourseStudent(Course course, User user, Boolean accessable) {
??????? this.course = course;
??????? this.user = user;
??????? this.accessable = accessable;
??? }
??? @Id
??? public Course getCourse() {
??????? return course;
??? }
??? public void setCourse(Course course) {
??????? this.course = course;
??? }
??? @Id
??? public User getUser() {
??????? return user;
??? }
??? public void setUser(User user) {
??????? this.user = user;
??? }
??? public Boolean getAccessable() {
??????? return accessable;
??? }
??? public void setAccessable(Boolean accessable) {
??????? this.accessable = accessable;
??? }
}
@Entity
public class Course extends BaseEntity {
??? private static final long serialVersionUID = 8768227695335084711L;
??? private Set<CourseTeacher> teachers;
??? private Set<CourseStudent> students;
???
??? @OneToMany(mappedBy="course",cascade=CascadeType.ALL)
??? public Set<CourseTeacher> getTeachers() {
??????? return teachers;
??? }
??? public void setTeachers(Set<CourseTeacher> teachers) {
??????? this.teachers = teachers;
??? }
??? @OneToMany(mappedBy="course")
??? public Set<CourseStudent> getStudents() {
??????? return students;
??? }
??? public void setStudents(Set<CourseStudent> students) {
??????? this.students = students;
??? }
}
?
?
參考文章:http://www.4ucode.com/Study/Topic/1070774
Hibernate可以通過*.hbm.xml配置文件能很好地把多對多關(guān)系拆分成兩個一對多的關(guān)系,但Hibernate Annotation的文檔中沒有說到這個點上來。下面通過實例說明用注解來實現(xiàn)多對多拆分成兩個一對多。
下面以商品Product和訂單Order之間的多對多關(guān)系來說明。
????? Product的屬性包括:
- id
- name
- price
Order的屬性包括:
- id
- date(下訂單的時間)
為什么要把多對多關(guān)系拆分成兩個一對多?
因為多對多關(guān)系不能保存兩個實體之間共有的屬性。比如,如何記錄訂單A中購買的商品B的數(shù)量呢?如果以多對多映射就不能實現(xiàn)了。
中間實體----用來記錄兩個多對多實體之間共有關(guān)系
在Product和Order之間的關(guān)系中,可以用一個OrderItem實體來表示兩者多對多中的眾多關(guān)系中的一個關(guān)系。即Product與OrderItem,Order與OrderItem之間的關(guān)系為一對多的關(guān)系。
OrderItem的屬性包括:
- product(假如當(dāng)前記錄的是商品C)
- order(假如當(dāng)前記錄的是訂單D)
- quantity(這里記錄的是訂單D中商品C的數(shù)量)
實例代碼(省略了類包引用):
復(fù)合主鍵類:
@Embeddable public class OrderItemPK implements Serializable{private Product product;private Order order;@ManyToOne@JoinColumn(name="product_id",referencedColumnName="id")public Product getProduct(){return product;}public void setProduct(Product product){this.product=product;}@ManyToOne@JoinColumn(name="order_id",referencedColumnName="id")public Order getOrder(){return order;}public void setOrder(Order order){this.order=order;}public boolean equals(Object object){...}public int hashCode(){...} }OrderItem類:
@Entity @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true) @Table(name="order_item") @IdClass(OrderItemPK.class) public class OrderItem implements Serializable{private Product product;private Order order;private int quantity;@Idpublic Product getProduct(){return product;}public void setProduct(Product product){this.product=product;}@Idpublic Order getOrder(){return order;}public void setOrder(Order order){this.order=order;}@Column(name="quantity")public int getQuantity(){return quantity;}public void setQuantity(int quantity){this.quantity=quantity;} }Product類:
@Entity @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true) @Table(name="product") public class Product implements Serializable{private int id;private String name;private double price;private Set<OrderItem> orderItems;@Id@GenericGenerator(name="g_id",strategy="increment")@GeneratedValue(generator="g_id")public int getId(){return id;}public void setId(int id){this.id=id;}public String getName(){return name;}public void setName(String name){this.name=name;}public double getPrice(){return price;}public void setPrice(double price){this.price=price;}@OneToMany(mappedBy="product")public Set<OrderItem> getOrderItems(){return orderItems;}public void setOrderItems(Set<OrderItem> orderItems){this.orderItems=orderItems;} }Order類:
@Entity @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true) @Table(name="tbl_order") public class Order implements Serializable{private int id;private Calendar date;private Set<OrderItem> orderItems;@Id@GenericGenerator(name="g_id",strategy="increment")@GeneratedValue(generator="g_id")public int getId(){return id;}public void setId(int id){this.id=id;}public Calendar getDate(){return date;}public void setDate(Calendar date){this.date=date;}@OneToMany(mappedBy="order")public Set<OrderItem> getOrderItems(){return orderItems;}public void setOrderItems(Set<OrderItem> orderItems){this.orderItems=orderItems;} }總結(jié)
以上是生活随笔為你收集整理的hibernate多对多映射拆成2个一对多映射(注解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hibernate 关联映射 之 多对多
- 下一篇: struts2访问session的两种方