hibernate多对多映射拆成2个一对多映射(注解)
hibernate的many to many确实很是方便我们处理实体和集合间的关系,并可以通过级联的方法处理集合,但有的时候many to many不能满足我们的需要,比如 用户<--->选课,典型的多对多关系,一般情况下,会生成
course_user(course_id,user_id);
但用户选课的时候最好加入审核功能,所以我们希望在中间自动生成的表中加入一个boolean字段,类似这种结构:
course_user(course_id,user_id,accessable);
这个时候我们可以把many to many拆分成2个many to one ,自己手动添加个中间表,这样扩展就好很多了。
代码如下:
@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配置文件能很好地把多对多关系拆分成两个一对多的关系,但Hibernate Annotation的文档中没有说到这个点上来。下面通过实例说明用注解来实现多对多拆分成两个一对多。
下面以商品Product和订单Order之间的多对多关系来说明。
Product的属性包括:
- id
- name
- price
Order的属性包括:
- id
- date(下订单的时间)
为什么要把多对多关系拆分成两个一对多?
因为多对多关系不能保存两个实体之间共有的属性。比如,如何记录订单A中购买的商品B的数量呢?如果以多对多映射就不能实现了。
中间实体----用来记录两个多对多实体之间共有关系
在Product和Order之间的关系中,可以用一个OrderItem实体来表示两者多对多中的众多关系中的一个关系。即Product与OrderItem,Order与OrderItem之间的关系为一对多的关系。
OrderItem的属性包括:
- product(假如当前记录的是商品C)
- order(假如当前记录的是订单D)
- quantity(这里记录的是订单D中商品C的数量)
实例代码(省略了类包引用):
复合主键类:
@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;
@Id
public Product getProduct(){
return product;
}
public void setProduct(Product product){
this.product=product;
}
@Id
public 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;
}
}
作者:BuildNewApp
出处:http://syxchina.cnblogs.com、 BuildNewApp.com
本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。



浙公网安备 33010602011771号