实体BEAN的七种关系之---------一对多单向
One-to-Many Unidirectional Relationship
一对多单向最典型的应用莫过于人和电话的关系了,我们一个人可以有很多个电话,有时候还经常会换号码,我们可以既有小灵通也有手机,家里还有固定电话,这就是很典型的一对多关系,为什么要是单向的呢,因为电话的易变性,这个号码可能今天是你的,明天就可能是别人的了,并且现在买手机号码是不需要身份证的,所以从电话号码是不可能查到你的身份证了.并且电话号码也不应该和人绑定,一般我们都是问别人电话是多少,却比较少去问一个号码是谁的(这种情况也有,就是你收到陌生人的电话或短信的时候).那我们还是先看代码吧.
首先我们还是先要定义一个人的实体类
/*
* Person.java
*
* Created on 2007-9-15, 0:11:58
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package
lbf.entitybean.test1;
import
java.io.Serializable;
import
java.util.List;
import
javax.persistence.CascadeType;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.GenerationType;
import
javax.persistence.Id;
import
javax.persistence.JoinColumn;
import
javax.persistence.OneToMany;
import
javax.persistence.OneToOne;
/**
*
*
@author
Admin
*/
@Entity
public
class
Person
implements
Serializable {
private
IDCard idCard;
private
static
final
long
serialVersionUID
=
1L
;
private
Long id;
private
String name;
private
String sex;
private
int
age;
private
Address address;
@OneToOne(cascade
=
CascadeType.ALL,optional
=
true
)
public
Address getAddress() {
return
address;
}
public
void
setAddress(Address address) {
this
.address
=
address;
}
@OneToMany(cascade
=
CascadeType.ALL)
@JoinColumn(name
=
"
personID
"
)
public
List
<
Phone
>
getPhones() {
return
phones;
}
public
void
setPhones(List
<
Phone
>
phones) {
this
.phones
=
phones;
}
private
List
<
Phone
>
phones;
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age
=
age;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name
=
name;
}
public
String getSex() {
return
sex;
}
public
void
setSex(String sex) {
this
.sex
=
sex;
}
public
void
setId(Long id) {
this
.id
=
id;
}
@Id
@GeneratedValue(strategy
=
GenerationType.AUTO)
public
Long getId() {
return
id;
}
@OneToOne(cascade
=
{CascadeType.ALL})
public
IDCard getIdCard() {
return
idCard;
}
public
void
setIdCard(IDCard iDCard) {
this
.idCard
=
iDCard;
}
}
然后是电话的实体类
/*
* Phone.java
*
* Created on 2007-9-18, 17:23:28
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package
lbf.entitybean.test1;
import
java.io.Serializable;
import
javax.persistence.CascadeType;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.GenerationType;
import
javax.persistence.Id;
import
javax.persistence.ManyToOne;
/**
*
*
@author
hadeslee
*/
@Entity
public
class
Phone
implements
Serializable {
private
static
final
long
serialVersionUID
=
1L
;
private
Long id;
private
String phoneNumber;
public
String getPhoneNumber() {
return
phoneNumber;
}
public
void
setPhoneNumber(String phoneNumber) {
this
.phoneNumber
=
phoneNumber;
}
public
void
setId(Long id) {
this
.id
=
id;
}
@Id
@GeneratedValue(strategy
=
GenerationType.AUTO)
public
Long getId() {
return
id;
}
}
我们可以在Person类里面发现如下注释
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="personID")
public List<Phone> getPhones() {
return phones;
}
它代表是一对多,一是指类本身,多是指这个成员,也就是一个类可以对应多个成员.
在一对多里面,无论是单向还是双向,映射关系的维护端都是在多的那一方,也就是Phone那里,因为要在数据库面表现的话,也只有让Phone起一个指向Person的外键,不可能在Person里面指向Phone,这一点和一对一不一样,一对一可以在任意一方起一个外键指向对方.可是一对多却不行了.在这里@JoinColumn这个注释指的却是在Phone里面的外键的列的名字,它并不像在一对一里面的注释指的是自己表里面的外键列名.这一点要特别注意一下.
如果是一对多的双向关系,那么这个注释就要应用到多的那边去了,虽然注释还在Person类里面,但是它起的效果却是在Phone里面起一个叫personID的外键, 因为多的那边要有外键指向少的这边.
如果你不加 @JoinColumn(name="personID")这个注释的话,那么JBOSS就会自动帮你生成一张中间表,它负现Person和Phone表之间的联系.它将会做如下事情:
CREATE
TABLE
PERSON_PHONE
(
PERSON_id
INT
,
PHONE_id
INT
);
ALTER
TABLE
PERSON_PHONE
ADD
CONSTRAINT
person_phone_unique
UNIQUE
(PHONE_id);
ALTER
TABLE
PERSON_PHONE
ADD
CONSTRAINT
personREFphone
FOREIGN
KEY
(PERSON_id)
REFERENCES
PERSON (id);
ALTER
TABLE
PERSON_PHONE
ADD
CONSTRAINT
personREFphone2
FOREIGN
KEY
(PHONE_id)
REFERENCES
PHONE (id);
所以我们最好还是指定一下,在Phone里面生成一个外键指向Person,看起来更好一些.