基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一不同的就是单向一对一关联中的外键字段具有唯一性约束。需在单向多对一映射中的实体类多的一端配置unique=“true”。
基于外键一对一映射可分为单向和双向两种。
单向
示例:
Person类
public class Person {
private int id;
private String name;
private int age;
private IdCard idCard;
//省略get/set方法
}
IdCard类
public class IdCard {
private int id;
private String code;
//省略get/set方法
}
Person.hbm.xml配置文件
<hibernate-mapping package="com.test.pojo">
<class name="Person">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<property name="age"/>
<!-- 多对一 name表示属性名 class指明属性对应的类
column指明数据库表中的列名
unique="true"时可以设置一对一的关系
-->
<many-to-one name="idCard" class="IdCard"
column="idCard_Id" foreign-key="fk_idCard"
unique="true" cascade="save-update"
not-null="true"></many-to-one>
</class>
</hibernate-mapping>
IdCard.hbm.xml配置文件
<hibernate-mapping package="com.test.pojo">
<class name="IdCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="code" />
</class>
</hibernate-mapping>
HibernateUtil类
public class HibernateUtil {
private static Configuration cfg=null;
private static SessionFactory factory=null;
private static Session session=null;
static{
cfg=new Configuration().configure();
factory=cfg.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build());
}
public static Session getSession(){
if(factory!=null)
return factory.openSession();
factory=cfg.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build());
return factory.openSession();
}
public static void closeSession(){
if(session!=null && session.isOpen())
session.close();
}
}
测试类
public class HibernateTest {
@Test
public void testCreateDB(){
Configuration cfg=new Configuration().configure();
SchemaExport se=new SchemaExport(cfg);
//第一个参数表示是否生成ddl脚本,第二个参数表示是否执行到数据库中
se.create(true, true);
}
/**
* 保存数据
*/
@Test
public void save(){
Session session=null;
Transaction tx=null;
try{
session=HibernateUtil.getSession();
tx=session.beginTransaction();
IdCard id1=new IdCard();
id1.setCode("124234545656767");
IdCard id2=new IdCard();
id2.setCode("120343435454556");
Person person1=new Person();
person1.setName("孙悟空");
person1.setAge(500);
person1.setIdCard(id1);
Person per=new Person();
per.setName("唐僧");
per.setAge(30);
per.setIdCard(id2);
Person per2=new Person();
per2.setName("白骨精");
per2.setAge(500);
per2.setIdCard(id1);
session.save(person1);
session.save(per);
//以下保存会出错
//session.save(per2);
tx.commit();
}catch(Exception e){
if(tx!=null)
tx.rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}
}
执行testCreateDB控制台打印信息如下:
alter table Person
drop
foreign key fk_idCard
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 auto_increment,
name varchar(255),
age integer,
idCard_Id integer not null,
primary key (id)
)
alter table Person
add constraint UK_lf26pluj4u3fh6oktbat4412b unique (idCard_Id)
alter table Person
add constraint fk_idCard
foreign key (idCard_Id)
references IdCard (id)
执行save控制台打印信息如下
Hibernate:
insert
into
IdCard
(code)
values
(?)
Hibernate:
insert
into
Person
(name, age, idCard_Id)
values
(?, ?, ?)
Hibernate:
insert
into
IdCard
(code)
values
(?)
Hibernate:
insert
into
Person
(name, age, idCard_Id)
values
(?, ?, ?)
双向
双向与单向代码不同的地方示例:
IdCard类
public class IdCard {
private int id;
private String code;
private Person person;
//省略get/set方法
}
IdCard.hbm.xml配置文件
<hibernate-mapping package="com.test.pojo">
<class name="IdCard">
<id name="id">
<generator class="native"></generator>
</id>
<property name="code" />
<one-to-one name="person" property-ref="idCard"></one-to-one>
</class>
</hibernate-mapping>
其余地方代码都与单向示例一样。