双向一对一
@OneToOne注解用来一对一映射;
需要在被维护关系的一端加上属性 mappedBy 来表示放弃维护关联关系;
例如:可以建立两个类 Company、Boss;
假设一个公司只有一个老板,而一个老板只有一个公司;只是这么假设;
Boss类:
维护关联关系的一端需要用@JoinColumn注解的name 属性来指定外键名;
注意:由于是一对一映射,需要加上unique=true属性;
@JoinColumn(name="b_id",unique=true)
@OneToOne
private Boss boss;
Company类:
不维护关联关系的一端要在@OneToOne里面添加mappedBy属性来指定用另一个类的哪个属性来映射关联关系;
也就是说mappedBy的值是另一个类中外键类属性的属性名;例如Boss类中的 private Company company;
有了mappedBy就不能用@JoinColumn;
@OneToOne(mappedBy="boss")
private Company company;
1.插入
//测试一对一添加
@Test
public void testInsert(){
Boss boss=new Boss();
boss.setBname("曹操老板");
Company company=new Company();
company.setCname("曹魏集团");
boss.setCompany(company);
company.setBoss(boss);
manager.persist(company);
manager.persist(boss);
}
结果:
Hibernate:
insert
into
tb_comp
(b_id, cname)
values
(?, ?)
Hibernate:
insert
into
tb_boss
(bname)
values
(?)
Hibernate:
update
tb_comp
set
b_id=?,
cname=?
where
cid=?
插入成功后,维护关联关系的company对应的表中会多出一列外键;
如果是先插入维护关联关系的一方,则会有一条update语句;
如果是先插入不维护关联关系的一方,这里是boss,将不会有update语句;
在插入时建议先插入没有外键的一方;
2.查询
1)如果查询维护关联关系的一端
//测试一对一查找
@Test
public void testFind(){
Company comp=manager.find(Company.class, 1);
}
结果:
Hibernate:
select
company0_.cid as cid1_1_1_,
company0_.b_id as b_id3_1_1_,
company0_.cname as cname2_1_1_,
boss1_.bid as bid1_0_0_,
boss1_.bname as bname2_0_0_
from
tb_comp company0_
left outer join
tb_boss boss1_
on company0_.b_id=boss1_.bid
where
company0_.cid=?
Hibernate:
select
company0_.cid as cid1_1_1_,
company0_.b_id as b_id3_1_1_,
company0_.cname as cname2_1_1_,
boss1_.bid as bid1_0_0_,
boss1_.bname as bname2_0_0_
from
tb_comp company0_
left outer join
tb_boss boss1_
on company0_.b_id=boss1_.bid
where
company0_.b_id=?
默认会通过左外链接来查询;并且发出两条查询语句;
可以通过在@OneToOne注解后面加上 fetch属性,改为懒加载;会只有一条查询语句;
@JoinColumn(name="b_id",unique=true)
@OneToOne(fetch=FetchType.LAZY)
private Boss boss;
改为懒加载后的结果:
Hibernate:
select
company0_.cid as cid1_1_0_,
company0_.b_id as b_id3_1_0_,
company0_.cname as cname2_1_0_
from
tb_comp company0_
where
company0_.cid=?
2)查询不维护关联关系的一端
//查询不维护关联关系的一端
@Test
public void testFind2(){
Boss boss=manager.find(Boss.class, 1);
}
结果:
Hibernate:
select
boss0_.bid as bid1_0_1_,
boss0_.bname as bname2_0_1_,
company1_.cid as cid1_1_0_,
company1_.b_id as b_id3_1_0_,
company1_.cname as cname2_1_0_
from
tb_boss boss0_
left outer join
tb_comp company1_
on boss0_.bid=company1_.b_id
where
boss0_.bid=?
会发出一条左外连接查询;
如果改为修改 fetch为懒加载 会发出两条查询语句;
因为Boss类对应的表中没有外键;
因此不可能生成通过外键id生成代理对象;
只能发出两条sql或进行左外连接查询否则无法处理关联的对象的信息 ;
通常不维持关联关系的一端不建议用懒加载;