hibernate多对多映射拆成2个一对多映射(注解)
hibernate的many to many確實(shí)很是方便我們處理實(shí)體和集合間的關(guān)系,并可以通過(guò)級(jí)聯(lián)的方法處理集合,但有的時(shí)候many to many不能滿足我們的需要,比如 用戶<--->選課,典型的多對(duì)多關(guān)系,一般情況下,會(huì)生成
course_user(course_id,user_id);
但用戶選課的時(shí)候最好加入審核功能,所以我們希望在中間自動(dòng)生成的表中加入一個(gè)boolean字段,類似這種結(jié)構(gòu):
course_user(course_id,user_id,accessable);
這個(gè)時(shí)候我們可以把many to many拆分成2個(gè)many to one ,自己手動(dòng)添加個(gè)中間表,這樣擴(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可以通過(guò)*.hbm.xml配置文件能很好地把多對(duì)多關(guān)系拆分成兩個(gè)一對(duì)多的關(guān)系,但Hibernate Annotation的文檔中沒(méi)有說(shuō)到這個(gè)點(diǎn)上來(lái)。下面通過(guò)實(shí)例說(shuō)明用注解來(lái)實(shí)現(xiàn)多對(duì)多拆分成兩個(gè)一對(duì)多。
下面以商品Product和訂單Order之間的多對(duì)多關(guān)系來(lái)說(shuō)明。
????? Product的屬性包括:
- id
- name
- price
Order的屬性包括:
- id
- date(下訂單的時(shí)間)
為什么要把多對(duì)多關(guān)系拆分成兩個(gè)一對(duì)多?
因?yàn)槎鄬?duì)多關(guān)系不能保存兩個(gè)實(shí)體之間共有的屬性。比如,如何記錄訂單A中購(gòu)買的商品B的數(shù)量呢?如果以多對(duì)多映射就不能實(shí)現(xiàn)了。
中間實(shí)體----用來(lái)記錄兩個(gè)多對(duì)多實(shí)體之間共有關(guān)系
在Product和Order之間的關(guān)系中,可以用一個(gè)OrderItem實(shí)體來(lái)表示兩者多對(duì)多中的眾多關(guān)系中的一個(gè)關(guān)系。即Product與OrderItem,Order與OrderItem之間的關(guān)系為一對(duì)多的關(guān)系。
OrderItem的屬性包括:
- product(假如當(dāng)前記錄的是商品C)
- order(假如當(dāng)前記錄的是訂單D)
- quantity(這里記錄的是訂單D中商品C的數(shù)量)
實(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个一对多映射(注解)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hibernate 关联映射 之 多对多
- 下一篇: Online Shopping网上商城数