1.插入
建一个部门类Dept和一个员工类Emp;
Emp对Dept是多对一的关系;因为一个部门有多个员工,而一个员工只有一个部门;
Emp类中添加一个Dept的属性;
@ManyToOne注解表示了员工和部门是多对一的关系;
@JoinColumn注解的name属性表示外键名;Emp表中会多出一个外键列;
//多对一,一个员工对应一个部门;而一个部门可对应多个员工;
@JoinColumn(name="d_id")
@ManyToOne
private Dept dept;
插入测试:
//测试多对一添加
@Test
public void testUpdate() {
//部门1
Dept dept=new Dept();
dept.setDname("军师");
//员工1
Emp emp=new Emp();
emp.setBirthday(new Date());
emp.setName("诸葛孔明");
emp.setSalary(1000);
emp.setDept(dept);
//员工2
Emp emp2=new Emp();
emp2.setBirthday(new Date());
emp2.setName("小懿子");
emp2.setSalary(5000);
emp2.setDept(dept);
//插入
manager.persist(dept);
manager.persist(emp);
manager.persist(emp2);
}
结果:
Hibernate:
insert
into
tb_dept
(dname)
values
(?)
Hibernate:
insert
into
tb_emp
(birthday, d_id, name, salary)
values
(?, ?, ?, ?)
Hibernate:
insert
into
tb_emp
(birthday, d_id, name, salary)
values
(?, ?, ?, ?)
可以看出,先插入Dept也就是少的一方,执行三条insert语句;
先插入Emp,后插入Dept结果:
Hibernate:
insert
into
tb_emp
(birthday, d_id, name, salary)
values
(?, ?, ?, ?)
Hibernate:
insert
into
tb_emp
(birthday, d_id, name, salary)
values
(?, ?, ?, ?)
Hibernate:
insert
into
tb_dept
(dname)
values
(?)
Hibernate:
update
tb_emp
set
birthday=?,
d_id=?,
name=?,
salary=?
where
id=?
Hibernate:
update
tb_emp
set
birthday=?,
d_id=?,
name=?,
salary=?
where
id=?
可以看出,先执行了三条插入语句,后执行了两条update语句;
因为Emp先插入时由于Dept还没插入,所以没有Dept的did;也就是外键;
等Dept插入后有了外键;
为了维持两张表的关联关系,执行了更新语句;给两个Emp添加外键;
为了提高效率,处理多对一的保存操作时,最好先保存少的一方;
2.查询
@Test
public void testSelect(){
manager.find(Emp.class, 1);
}
结果:
Hibernate:
select
emp0_.id as id1_1_1_,
emp0_.birthday as birthday2_1_1_,
emp0_.d_id as d_id5_1_1_,
emp0_.name as name3_1_1_,
emp0_.salary as salary4_1_1_,
dept1_.did as did1_0_0_,
dept1_.dname as dname2_0_0_
from
tb_emp emp0_
left outer join
tb_dept dept1_
on emp0_.d_id=dept1_.did
where
emp0_.id=?
可以看出使用左外连接来获取关联对象;
1)懒加载查询
可在@ManyToOne注解后面将fetch属性改为LAZY来使用懒加载;
懒加载会在需要用到Dept的属性时才执行查询Dept的sql语句;可以节省资源;
//多对一,一个员工对应一个部门;而一个部门可对应多个员工;
@JoinColumn(name="d_id")
@ManyToOne(fetch=FetchType.LAZY)
private Dept dept;
结果:
Hibernate:
select
emp0_.id as id1_1_0_,
emp0_.birthday as birthday2_1_0_,
emp0_.d_id as d_id5_1_0_,
emp0_.name as name3_1_0_,
emp0_.salary as salary4_1_0_
from
tb_emp emp0_
where
emp0_.id=?
可以看出没有查询外键;
3.删除
因为有外键关联;在删除多对一,少的一方时会报错;
例如当Dept的一条记录还被Emp中的记录关联时,就无法删除,会报错;
4.更新
在many to one 映射中,可以通过one的一方来修改many;
//测试修改
@Test
public void testUpdate(){
Emp emp=manager.find(Emp.class, 1);
emp.getDept().setDname("丞相");
}
结果:
Hibernate:
select
emp0_.id as id1_1_0_,
emp0_.birthday as birthday2_1_0_,
emp0_.d_id as d_id5_1_0_,
emp0_.name as name3_1_0_,
emp0_.salary as salary4_1_0_
from
tb_emp emp0_
where
emp0_.id=?
Hibernate:
select
dept0_.did as did1_0_0_,
dept0_.dname as dname2_0_0_
from
tb_dept dept0_
where
dept0_.did=?
Hibernate:
update
tb_dept
set
dname=?
where
did=?
可以看出执行了两条查询语句和一条更新语句;