在讲hibernate的 一对多、多对一单向关联 一对多双向关联的映射关系之前首先来看看数据库表的设计。数据库表的设计好坏直接关系着程序设计的简单与复杂。
人person和梦dream是一对多的关系,那么再设计数据库表的时候,是将personid添加到dream表中(即将一加入多的一方)好,还是将dreamid添加到person表中(即将多的一方加入到一)好呢?
首先假设dreamid添加到person表中,则具体表如下:
dream表
dreamnid | dreamname |
1 | Make money |
2 | Travel world |
person表
personid | person | dreamid |
1 | shining | 1 |
1 | shining | 2 |
2 | Sharing | 1 |
2 | sharing | 2 |
那么在hibernate的关系映射中是应该选择在person类中添加dream的set集合,进行@one2many,还是在dream类中添加person,进行@many2one的映射,还是进行综合以上两种映射进行一对多的双向映射呢?
单向关联就是只使用单方面来维护关系,双向关联就是双方面都要维护关系,一般具体决定使用单向关联还是双向关联,要取决于你的业务需求。如果单向关联能够满足要求建议尽可能使用单向关联,因为使用双向关联,关系复杂了,在编程的时候就容易出错。另外,关联关系还涉及到控制权的问题,在<one-to-many>映射时最好把控制权交给多的哪一方进行控制(控制就是维护两者之间的关系)
下面总结一下单向一对多关联映射时将控制权交给一的一方的缺点:
如果在进行映射时选择在person类中添加dream的set集合,进行@one2many的映射,那么在向数据库中添加数据时,必须首先保存多的一端(dream表)后才可以保存一的一端(person)。因为在保存多的一端时dream并不知道是否有相对应的person(即dream不知道是否有人有这个梦想),所以在只能将维护的关系字段设置为null,如果为非空则无法保存数据(此时一的一端还没保存不能直接调用)。因为是一的一端维护关系,多以在保存一的一端时,会发出多余的update语句维护多的一端的外键关系。
在<one-to-many>映射时最好把控制权交给多的哪一方的具体做法的举例:
一个order包括多个orderitem,在order表中的 Set<OrderItem> getOrderItem()方法上添加@OneToMany,同时指定以itermid为关联主键@JoinColumn(name="itermid")
@Entity
public class Orders {
@Id
@GeneratedValue
public int getOrderid() {
return orderid;
}
public void setOrderid(int orderid) {
this.orderid = orderid;
}
public Date getDatatime() {
return datatime;
}
public void setDatatime(Date datatime) {
this.datatime = datatime;
}
public void setOrderItem(Set<OrderItem> orderItem) {
this.orderItem = orderItem;
}
@OneToMany
@JoinColumn(name="itermid")
public Set<OrderItem> getOrderItem() {
return orderItem;
}
private int orderid;
private Set<OrderItem> orderItem = new HashSet<OrderItem>();
private Date datatime;
}
@Entity
public class OrderItem {
private int itermid;
@Id
@GeneratedValue
public int getItermid() {
return itermid;
}
public void setItermid(int itermid) {
this.itermid = itermid;
}
public int getOrdernum() {
return ordernum;
}
public void setOrdernum(int ordernum) {
this.ordernum = ordernum;
}
private int ordernum;
}