hibernate基于主键的一对一关系,有两种,单向和双向。基于主键的一对一关系指的是,两张表使用的是同一个id。
现在先说说单向
新建一个java项目,名称是:15hibernate_single_one_to_one_primary
结构如下:
需要的jar包和如何从hibernate上获得jar包,请参见《Hibernate环境搭建和配置》
实体类IdCard、Person、HibernateUtil、hibernate.cfg.xml和hibernateTest ,
请参见《hibernate基于外键的一对一映射--单向和双向》
IdCard.hbm.xml配置文件代码:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.robert.pojo">
<class name="IdCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="code"></property>
</class>
</hibernate-mapping>
Person.hbm.xml配置文件代码:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.robert.pojo">
<class name="Person">
<id name="id">
<!-- foreign表示引用外键,即person的主键是关联的外键,这个外键是使用idCard的主键 -->
<generator class="foreign">
<!-- 表示引用idCard属性所对应的主键 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"></property>
<property name="age"></property>
<!-- constrained表示一对一外键关联 -->
<one-to-one name="idCard" constrained="true" cascade="save-update" />
</class>
</hibernate-mapping>
使用Junit4运行testCreateDB,重新生成数据库表。
alter table Person
drop
foreign key FK_3blpx78aucutb5umaelf9essh
drop table if exists IdCard
drop table if exists Person
create table IdCard (
id integer not null auto_increment,
code varchar(255),
primary key (id)
)
create table Person (
id integer not null,
name varchar(255),
age integer,
primary key (id)
)
alter table Person
add constraint FK_3blpx78aucutb5umaelf9essh
foreign key (id)
references IdCard (id)
testSave()方法代码:
/**
* 保存数据
*
* @throws HibernateException
* @throws SerialException
* @throws SQLException
* @throws IOException
*/
@Test
public void testSave() throws HibernateException, SerialException,
SQLException, IOException {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtil.getSession();
tx = session.beginTransaction();
IdCard idCard = new IdCard() ;
idCard.setCode("1525271000000000000") ;
Person person = new Person() ;
person.setAge(23) ;
person.setName("张三") ;
person.setIdCard(idCard) ;
session.save(person) ;
IdCard idCard2 = new IdCard() ;
idCard2.setCode("11011010000000000") ;
Person person2 = new Person() ;
person2.setAge(24) ;
person2.setName("李四") ;
person2.setIdCard(idCard2) ;
session.save(person2);
// Person person3 = new Person() ;
// person3.setAge(25) ;
// person3.setName("王五") ;
// person3.setIdCard(idCard2) ;//依然使用idCard2身份信息
//
// session.save(person3) ;
tx.commit();
} catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
throw e;
} finally {
HibernateUtil.closeSession();
}
}
控制台打印的sql语句如:
Hibernate:
insert
into
IdCard
(code)
values
(?)
Hibernate:
insert
into
Person
(name, age, id)
values
(?, ?, ?)
Hibernate:
insert
into
IdCard
(code)
values
(?)
Hibernate:
insert
into
Person
(name, age, id)
values
(?, ?, ?)
==================================================================================
接下来是多向的
项目结构和大部分内容和上面是一样的,只有两个地方不一样,那就是
IdCard实体类,里面关联了Person属性,如:
package com.robert.pojo;
public class IdCard {
private int id ;
private String code ;//身份证号
private Person person ;//关联person
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
对应的IdCard.hbm.xml代码也有多不同,
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.robert.pojo">
<class name="IdCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="code"></property>
<one-to-one name="person" constrained="true" />
</class>
</hibernate-mapping>
至于为什么是这么写,不用记,从文档中可以找到,如图: