6.7.3
一对一映射
一个人(
Person
)只有唯一的身份证号
(IDCard)
,
Person
与
IDCard
是一对一关系。下面就以他们为例介绍存在
一对一关系的实体
Bean
开发过程
需要映射的数据库表
person
字段名称字段类型属性描述
personid (
主键
) Int(11) not null
人员
ID
PersonName Varchar(32) not null
姓名
sex Tinyint(1) not null
性别
age Smallint(6) not null
年龄
birthday Datetime null
出生日期
idcard
字段名称字段类型属性描述
id (
主键
) Int(11) not null
流水号
cardno Varchar(18) not null
身份证号
Person_ID Int(11) not null
作为外键指向
person
表的
personid
一对一关系需要在关系维护端(
owner side
)的
@OneToOne
注释中定义
mappedBy
属性。在关系被维护端(
inverse
side
)建立外键列指向关系维护端的主键列。
下面是关系维护端
Person.java
的源代码:
package com.zhaosoft.bean;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@SuppressWarnings("serial")
@Entity
@Table(name = "person")
public class Person implements Serializable {
private Integer personid;
private String name;
private boolean sex;
private Short age;
private Date birthday;
private IDCard idcard;
@Id
@GeneratedValue
public Integer getPersonid() {
return personid;
}
public void setPersonid(Integer personid) {
this.personid = personid;
}
@Column(name = "PersonName", nullable = false, length = 32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(nullable = false)
public boolean getSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Column(nullable = false)
public Short getAge() {
return age;
}
public void setAge(Short age) {
this.age = age;
}
@Temporal(value = TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
/***************************************************************************
* 一对一关系需要在关系维护端(owner side)的@OneToOne 注释中定义mappedBy 属性。在关系被维护端 (inverse
* side)建立外键列指向关系维护端的主键列。
*
* @OneToOne 注释指明Person 与IDCard 为一对一关系,@OneToOne
* 注释五个属性:targetEntity、cascade、fetch、 optional 和mappedBy,
* 前四个属性的具体含义与@ManyToOne 注释的同名属性一一对应,请大家参考前面章节中 的内容,fetch
* 属性默认值是FetchType.EAGER。mappedBy 属性的具体含义与@OneToMany 注释的同名属性相同。
* 上面的optional = true 设置idcard 属性可以为null,也就是允讦没有身份证,未成年人就是没有身份证的。
**************************************************************************/
@OneToOne(optional = true, cascade = CascadeType.ALL, mappedBy = "person")
public IDCard getIdcard() {
return idcard;
}
public void setIdcard(IDCard idcard) {
this.idcard = idcard;
}
}
IDCard.java
package
com.zhaosoft.bean;
import
java.io.Serializable;
import
javax.persistence.CascadeType;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
import
javax.persistence.JoinColumn;
import
javax.persistence.OneToOne;
import
javax.persistence.Table;
@SuppressWarnings
(
"serial"
)
@Entity
@Table
(name =
"IDCard"
)
public
class
IDCard
implements
Serializable {
private
Integer
id
;
private
String
cardno
;
private
Person
person
;
public
IDCard() {
}
public
IDCard(String cardno) {
this
.
cardno
= cardno;
}
@Id
@GeneratedValue
public
Integer getId() {
return
id
;
}
public
void
setId(Integer id) {
this
.
id
= id;
}
@Column
(nullable =
false
, length = 18, unique =
true
)
public
String getCardno() {
return
cardno
;
}
public
void
setCardno(String cardno) {
this
.
cardno
= cardno;
}
/***************************************************************************
*
@OneToOne
注释指明
IDCard
与
Person
为一对一关系,
IDCard
是关系被维护端,
optional
=
false
*
设置
person
属性
值不能为
null
,也就是身份证必须有对应的主人。
*
@JoinColumn
(name
=
"Person_ID",
referencedColumnName
=
"personid",unique
=true)
*
指明
IDCard
对应表的
Person_ID
列作为外键与
Person
对应表的
personid
列进行关联
,
unique
=
*
true
指明
Person_ID
列的值不可重复。
*
**************************************************************************/
@OneToOne
(optional =
false
, cascade = CascadeType.
REFRESH
)
@JoinColumn
(name =
"Person_ID"
, referencedColumnName =
"personid"
, unique =
true
)
public
Person getPerson() {
return
person
;
}
public
void
setPerson(Person person) {
this
.
person
= person;
}
}
为了使用上面的实体Bean,我们定义一个Session Bean 作为他的使用者。下面是Session Bean 的业务接口,他定
义了四个业务方法insertPerson,getPersonByID,updatePersonInfo 和deletePerson, 四个方法的业务功能是:
insertPerson 添加一个人员(带一个身份证)进数据库
getPersonByID 获取指定编号的人员
updatePersonInfo 更新人名及身份证号
deletePerson 删除人员,连同其身份证一起删除
下面是Session Bean 的业务接口及实现类
package
com.zhaosoft.session;
import
java.util.Date;
import
java.util.List;
import
com.zhaosoft.bean.Person;
public
interface
OneToOneDAO {
public
void
insertPerson(String name,
boolean
sex,
short
age, Date birthday,String cardID);
public
Person getPersonByID(Integer orderid);
public
void
updatePersonInfo(Integer personid, String newname, String newIDcard);
public
void
deletePerson(Integer personid);
public
List getPersonByDate(Date a);
}
OneToOneDAOBean.java
package
com.zhaosoft.session;
import
java.util.Date;
import
java.util.List;
import
javax.ejb.Remote;
import
javax.ejb.Stateless;
import
javax.persistence.EntityManager;
import
javax.persistence.PersistenceContext;
import
javax.persistence.Query;
import
com.zhaosoft.bean.IDCard;
import
com.zhaosoft.bean.Person;
@Stateless
@Remote
( { OneToOneDAO.
class
})
public
class
OneToOneDAOBean
implements
OneToOneDAO {
@PersistenceContext
protected
EntityManager
em
;
/***************************************************************************
*
插入数据
*
**************************************************************************/
public
void
insertPerson(String name,
boolean
sex,
short
age,
Date birthday, String cardID) {
Person person =
new
Person();
person.setName(name);
person.setSex(sex);
person.setAge(Short.valueOf(age));
person.setBirthday(birthday);
IDCard idcard =
new
IDCard(cardID);
idcard.setPerson(person);
person.setIdcard(idcard);
em
.persist(person);
}
public
Person getPersonByID(Integer personid) {
Person person =
em
.find(Person.
class
, personid);
return
person;
}
public
void
updatePersonInfo(Integer personid, String newname,
String newIDcard) {
Person person =
em
.find(Person.
class
, personid);
if
(person !=
null
) {
person.setName(newname);
if
(person.getIdcard() !=
null
) {
person.getIdcard().setCardno(newIDcard);
}
em
.merge(person);
}
}
public
List getPersonByDate(Date a) {
//
获取指定
personid
的人员
Query query =
em
.createQuery(
"select p from Person p where p.birthday=:btd"
);
query.setParameter(
"btd"
,a,javax.persistence.TemporalType.
DATE
);
List result = query.getResultList();
return
result;
}
public
void
deletePerson(Integer personid) {
Person person =
em
.find(Person.
class
, personid);
if
(person !=
null
)
em
.remove(person);
}
}
下面是Session Bean 的JSP 客户端代码:
OneToOneTest.jsp
<%@
page
contentType
=
"text/html; charset=GBK"
%>
<%@
page
import
=
"com.zhaosoft.session.OneToOneDAO,
com.zhaosoft.bean.*,
javax.naming.*,
java.util.Date,
java.text.SimpleDateFormat,
java.util.*"
%>
<%
Properties props =
new
Properties();
props.setProperty(
"java.naming.factory.initial"
,
"org.jnp.interfaces.NamingContextFactory"
);
props.setProperty(
"java.naming.provider.url"
,
"localhost:1099"
);
props.setProperty(
"java.naming.factory.url.pkgs"
,
"org.jboss.naming"
);
InitialContext ctx =
new
InitialContext(props);
try
{
String outformate =
"<font color=blue>CMD>>Out>></font> "
;
OneToOneDAO oneToonedao = (OneToOneDAO) ctx.lookup(
"OneToOneDAOBean/remote"
);
SimpleDateFormat formatter =
new
SimpleDateFormat(
"yyyy-MM-dd"
);
SimpleDateFormat formatter1 =
new
SimpleDateFormat(
"MMddhhmmss"
);
String endno = formatter1.format(
new
Date()).toString();
oneToonedao.insertPerson(
"
黎活明"
,
true
, (
short
)26,formatter.parse(
"1980-9-30"
),
"44011"
+endno);
//
添加时请注意,身份证号不要重复,因为数据库字段身份证号是唯一的
Person person = oneToonedao.getPersonByID(
new
Integer(1));
if
(person!=
null
){
out.println(outformate +
"
寻找编号为1的人员<br>"
);
out.println(
"
姓名:"
+ person.getName() +
"
身份证:"
+
person.getIdcard().getCardno() +
"<br>"
);
}
else
{
out.println(
"
没有找到编号为1的人员<br>"
);
}
out.println(outformate +
"
更新编号为1的人员的姓名为李明,身份证号为33012"
+endno
+
"<br>"
);
oneToonedao.updatePersonInfo(
new
Integer(1),
"
李明"
,
"33012"
+endno);
out.println(
"================
删除编号为3的人员==============<br>"
);
oneToonedao.deletePerson(
new
Integer(3));
}
catch
(Exception e) {
out.println(e.getMessage());
}
%>