一、关联关系 多对多
栗子:一个员工可以有写多个项目,一个项目也是由多个程序员来完成,这就是一个典型的多对多实例
下面给根据实例提取出两个实体类 Employee (员工实体), Project (项目实体)。
一。单向的多对多:(提添加一个项目,并给这个项目添加两个员工。)
在员工表中植入Project属性
配置Employee.hbm.xml文件:
开始单侧:
@Test
//双向多对多关联关系 2.添加多个员工到一个部门下
public void manytomanyt1(){
Session session = HibernateUtil.getSession();
Transaction tx=session.beginTransaction();
Employee emp=new Employee();
emp.setEmpname("山鸡");
Project pro1=new Project();
pro1.setProname("安防部门");
Project pro2=new Project();
pro2.setProname("财务部门");
emp.getProjects().add(pro1);
emp.getProjects().add(pro2);
session.save(emp);
session.save(pro1);
session.save(pro2);
tx.commit();
}
结果:
二。多对多双向(查询项目下有几个员工/查询每个员工有几个项目)
在项目表中植入员工Employee属性:
配置Project.hbm.xml文件(同上):
测试:
@Test
//双向多对多关联关系 1.检索员工姓名并查出项目名称
public void t(){
Session session = HibernateUtil.getSession();
Employee employee = session.get(Employee.class, 29);
System.out.println("员工名称:"+employee.getEmpname());
System.out.println("员工所在项目:");
for (Project project:employee.getProjects()){
System.out.println(project.getProname());
}
}
结果:
Hibernate:
select
employee0_.empid as empid1_2_0_,
employee0_.empname as empname2_2_0_
from
ANNAN.Employee employee0_
where
employee0_.empid=?
员工名称:山鸡
员工所在项目:
Hibernate:
select
projects0_.eid as eid1_5_0_,
projects0_.pid as pid2_5_0_,
project1_.proid as proid1_3_1_,
project1_.proname as proname2_3_1_
from
empAndPro projects0_
inner join
ANNAN.Project project1_
on projects0_.pid=project1_.proid
where
projects0_.eid=?
安防部门
财务部门
二、延迟加载
延迟加载(lazy load懒加载)是当在真正需要数据时,才执行SQL语句进行查询,避免了无谓的性能开销。
延迟加载分类:
01.类级别的查询策略
02.一对多和多对多关联的查询策略
03.多对一关联的查询策略
一。类级别的查询策略:立即检索和延迟检索,默认为延迟检索
//类级别的延迟加载
@Test
public void t3(){
//默认lazy为true
Session session = HibernateUtil.getSession();
Employee employee = session.load(Employee.class, 29);
System.out.println();
}
效果:
当Class类 的lazy为false时:
效果:
三、对多和多对多关联查询策略
:::::::一对多或者多对多检索策略由lazy和fetch共同确定:::::::
在映射文件中,用<set>元素来配置一对多关联及多对多关联关系。<set>元素有lazy和fetch属性
1.lazy的值为true时:延迟加载
结果:
2.lazy的值为false时:立即加载
fetch取值
Join:迫切左外连接
Select:多条简单SQL(默认值)
Subselect:子查询
fetch和lazy组合
解析:fetch=”join” lazy会被忽略,迫切左外连接的立即检索
Fetch=”select” lazy=”false” 多条简单SQL立即检索
Fetch=”select” lazy=”true” 多条语句延迟检索
Fetch=”select” lazy=”extra” 多条语句及其懒惰检索
Fetch=”subselect” lazy=”false” 子查询立即检索
Fetch=”subselect” lazy=”true” 子查询延迟检索
Fetch=”subselect” lazy=”extra” 子查询及其懒惰检索
Join:
<set name="projects" table="empAndPro" fetch="join">
Hibernate:
select
employee0_.empid as empid1_2_0_,
employee0_.empname as empname2_2_0_,
projects1_.eid as eid1_5_1_,
project2_.proid as pid2_5_1_,
project2_.proid as proid1_3_2_,
project2_.proname as proname2_3_2_
from
ANNAN.Employee employee0_
left outer join
empAndPro projects1_
on employee0_.empid=projects1_.eid
left outer join
ANNAN.Project project2_
on projects1_.pid=project2_.proid
where
employee0_.empid=?
员工名称:山鸡
员工所在项目:
财务部门
安防部门
默认select:
<set name="projects" table="empAndPro" fetch="select">
Hibernate:
select
employee0_.empid as empid1_2_0_,
employee0_.empname as empname2_2_0_
from
ANNAN.Employee employee0_
where
employee0_.empid=?
员工名称:山鸡
员工所在项目:
Hibernate:
select
projects0_.eid as eid1_5_0_,
projects0_.pid as pid2_5_0_,
project1_.proid as proid1_3_1_,
project1_.proname as proname2_3_1_
from
empAndPro projects0_
inner join
ANNAN.Project project1_
on projects0_.pid=project1_.proid
where
projects0_.eid=?
安防部门
财务部门
3.lazy的值为extra时:加强延迟加载:(
只有访问集合对象的属性时才会加载,访问集合本身的属性时(例如,集合大小,生成count),不会立即加载。
)
结果:
System.out.println(projects.size());
Hibernate:
select
employee0_.empid as empid1_2_0_,
employee0_.empname as empname2_2_0_
from
ANNAN.Employee employee0_
where
employee0_.empid=?
Hibernate:
select
count(pid)
from
empAndPro
where
eid =?
2