public class Person {
private Integer pid;
private String name;
private Address address;
...
}
----------------------------------------
public class Address {
private Integer aid;
private String name;
private Person person;
...
}
1.0 基于外鍵的一對一
<?xml version="1.0" encoding="UTF-8"?>
<!-- Person.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
<class name="Person" table="t_Person" >
<id name="pid" column="pid">
<generator class="native"></generator>
</id>
<property name="name"></property>
<many-to-one name="address" class="Address" column="aid" unique="true"></many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Address.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
<class name="Address" table="t_Address" >
<id name="aid" column="aid">
<generator class="native"></generator>
</id>
<property name="name"></property>
<!-- property-ref指定關聯(lián)類的一個屬性,來對應自己,意思是:person的address指向我 -->
<one-to-one name="person" property-ref="address" class="Person"/>
</class>
</hibernate-mapping>
mysql> show create table t_person;
+----------+--------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------+
| Table | Create Table
|
+----------+--------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-----------------------------------+
| t_person | CREATE TABLE `t_person` (
`pid` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`aid` int(11) DEFAULT NULL,
PRIMARY KEY (`pid`),
UNIQUE KEY `aid` (`aid`),
KEY `FK41C0D9A019FE94E7` (`aid`),
CONSTRAINT `FK41C0D9A019FE94E7` FOREIGN KEY (`aid`) REFERENCES `t_address` (`a
id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+----------+--------------------------------------------------------------------
說白了,其實是一種特殊的一對多,多個person對一個address,但是person必須不重復
1.1添加
@Test
public void add(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=new Person("好人劉強東");
Address a=new Address("中關村");
p.setAddress(a);
session.save(p);
session.save(a);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
1.2查找
@Test
public void find(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=(Person) session.get(Person.class, 1);
// System.out.println(p.getAddress());
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
這里主要的問題是,他不級聯(lián)查
Hibernate:
select
person0_.pid as pid1_0_,
person0_.name as name1_0_,
person0_.aid as aid1_0_
from
t_Person person0_
where
person0_.pid=?
通過另一端address來查,
@Test
public void findByAddress(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Address a=(Address) session.get(Address.class, 1);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
Hibernate:
select
address0_.aid as aid0_1_,
address0_.name as name0_1_,
person1_.pid as pid1_0_,
person1_.name as name1_0_,
person1_.aid as aid1_0_
from
t_Address address0_
left outer join
t_Person person1_
on address0_.aid=person1_.aid
where
address0_.aid=?
結(jié)論: one-to-one 標簽修飾后,他是主動選擇每次查詢都用join的,這里因為一對一不需要考慮數(shù)據(jù)集太大的問題;
@Test
public void update(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Address a=(Address) session.get(Address.class, 1);
a.getPerson().setName("劉強東");
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
Hibernate:
select
address0_.aid as aid0_1_,
address0_.name as name0_1_,
person1_.pid as pid1_0_,
person1_.name as name1_0_,
person1_.aid as aid1_0_
from
t_Address address0_
left outer join
t_Person person1_
on address0_.aid=person1_.aid
where
address0_.aid=?
Hibernate:
update
t_Person
set
name=?,
aid=?
where
pid=?
1.3刪除
@Test
public void deleteByAddress(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Address a=(Address) session.get(Address.class, 1);
session.delete(a);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
這里會出錯,正確的方法:
@Test
public void deleteByPerson(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=(Person)session.get(Person.class, 1);
session.delete(p);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
主要是因為:

2.0 同步主鍵式的一對一
<?xml version="1.0" encoding="UTF-8"?>
<!-- Address.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
<class name="Address" table="t_Address" >
<id name="aid" column="aid">
<generator class="foreign">
<!-- 主鍵根據(jù)哪個一屬性對應的表來生成,這里是屬性名,切記 -->
<param name="property">person</param>
</generator>
</id>
<property name="name"></property>
<!--
constrained: 約束
name:依然是屬性名
-->
<one-to-one name="person" constrained="true"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Person.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
<class name="Person" table="t_Person" >
<id name="pid" column="pid">
<!-- 由這里提供主鍵 -->
<generator class="native"></generator>
</id>
<property name="name"></property>
<one-to-one name="address"/>
</class>
</hibernate-mapping>
2.1 添加
@Test
public void add(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=new Person("好人劉強東");
Address a=new Address("中關村");
a.setPerson(p);
p.setAddress(a);
session.save(p);
session.save(a);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
結(jié)果:
Hibernate:
insert
into
t_Person
(name)
values
(?)
Hibernate:
insert
into
t_Address
(name, aid)
values
(?, ?)
2.2.1級聯(lián)添加
<one-to-one name="address" cascade="all"/>
@Test
public void add(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=new Person("好人劉強東");
Address a=new Address("中關村");
a.setPerson(p);
p.setAddress(a);
session.save(p);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
Hibernate:
insert
into
t_Person
(name)
values
(?)
Hibernate:
insert
into
t_Address
(name, aid)
values
(?, ?)
2.2 更新
刪掉級聯(lián),繼續(xù)
考慮更新
@Test
public void updateByAddress(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Address a=(Address) session.get(Address.class, 1);
a.getPerson().setName("劉強東");
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
Hibernate:
select
address0_.aid as aid0_0_,
address0_.name as name0_0_
from
t_Address address0_
where
address0_.aid=?
Hibernate:
select
person0_.pid as pid1_1_,
person0_.name as name1_1_,
address1_.aid as aid0_0_,
address1_.name as name0_0_
from
t_Person person0_
left outer join
t_Address address1_
on person0_.pid=address1_.aid
where
person0_.pid=?
Hibernate:
update
t_Person
set
name=?
where
pid=?
2.3 刪除
@Test
public void deleteByAddress(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Address a=(Address) session.get(Address.class, 1);
session.delete(a);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
結(jié)果只刪除了address,因為沒有設級聯(lián)
2.3.1 級聯(lián)刪除
添加級聯(lián)
<!--person-->
<one-to-one name="address" cascade="all"/>
public void deleteByPerson(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
// ------------------------------------------------------
Person p=(Person)session.get(Person.class, 1);
session.delete(p);
// ------------------------------------------------------
session.getTransaction().commit();
session.close();
}
Hibernate:
select
person0_.pid as pid1_1_,
person0_.name as name1_1_,
address1_.aid as aid0_0_,
address1_.name as name0_0_
from
t_Person person0_
left outer join
t_Address address1_
on person0_.pid=address1_.aid
where
person0_.pid=?
Hibernate:
delete
from
t_Address
where
aid=?
Hibernate:
delete
from
t_Person
where
pid=?