area与project 一对多
3.0后版本默认" lazy="true" ,不能加,加会报错
1、<many-to-one name="area" class="com.xxxxxxx.site.entity.Area" fetch="select" lazy="false">
Hibernate: select count(*) as col_0_0_ from area area0_Hibernate: select area0_.id as id1_, area0_.name as name1_, area0_.image as image1_, area0_.type as type1_ from area area0_ limit ?
Hibernate: select project0_.area_id as area5_1_, project0_.id as id1_, project0_.id as id2_0_, project0_.name as name2_0_, project0_.content as content2_0_, project0_.image as image2_0_, project0_.area_id as area5_2_0_ from project project0_ where project0_.area_id in (?, ?, ?, ?, ?)
Hibernate: select count(*) as col_0_0_ from project project0_
Hibernate: select project0_.id as id2_, project0_.name as name2_, project0_.content as content2_, project0_.image as image2_, project0_.area_id as area5_2_ from project project0_ limit ?
Hibernate: select area0_.id as id1_0_, area0_.name as name1_0_, area0_.image as image1_0_, area0_.type as type1_0_ from area area0_ where area0_.id in (?, ?, ?)
Hibernate: select project0_.area_id as area5_1_, project0_.id as id1_, project0_.id as id2_0_, project0_.name as name2_0_, project0_.content as content2_0_, project0_.image as image2_0_, project0_.area_id as area5_2_0_ from project project0_ where project0_.area_id in (?, ?, ?)
2、<many-to-one name="area" class="com.xxxxxxx.site.entity.Area" fetch="select>
Hibernate: select count(*) as col_0_0_ from area area0_
Hibernate: select area0_.id as id1_, area0_.name as name1_, area0_.image as image1_, area0_.type as type1_ from area area0_ limit ?
Hibernate: select count(*) as col_0_0_ from project project0_
Hibernate: select project0_.id as id2_, project0_.name as name2_, project0_.content as content2_, project0_.image as image2_, project0_.area_id as area5_2_ from project project0_ limit ?
3、<set name="project" inverse="true" cascade="all,delete-orphan" lazy="false">
Hibernate: select count(*) as col_0_0_ from project project0_
Hibernate: select project0_.id as id2_, project0_.name as name2_, project0_.content as content2_, project0_.image as image2_, project0_.area_id as area5_2_ from project project0_ limit ?
Hibernate: select area0_.id as id1_0_, area0_.name as name1_0_, area0_.image as image1_0_, area0_.type as type1_0_ from area area0_ where area0_.id in (?, ?, ?)
Hibernate: select project0_.area_id as area5_1_, project0_.id as id1_, project0_.id as id2_0_, project0_.name as name2_0_, project0_.content as content2_0_, project0_.image as image2_0_, project0_.area_id as area5_2_0_ from project project0_ where project0_.area_id in (?, ?, ?)
4、<set name="project" inverse="true" cascade="all,delete-orphan" >、
报错版本
Hibernate: select count(*) as col_0_0_ from project project0_Hibernate: select project0_.id as id2_, project0_.name as name2_, project0_.content as content2_, project0_.image as image2_, project0_.area_id as area5_2_ from project project0_ limit ?
System.out.println("2!!!!!!!"+projectList.get(0).getArea()); 报错
正确版本Hibernate: select count(*) as col_0_0_ from project project0_
Hibernate: select project0_.id as id2_, project0_.name as name2_, project0_.content as content2_, project0_.image as image2_, project0_.area_id as area5_2_ from project project0_ limit ?
Hibernate: select area0_.id as id1_0_, area0_.name as name1_0_, area0_.image as image1_0_, area0_.type as type1_0_ from area area0_ where area0_.id in (?, ?, ?)
Hibernate: select project0_.area_id as area5_1_, project0_.id as id1_, project0_.id as id2_0_, project0_.name as name2_0_, project0_.content as content2_0_, project0_.image as image2_0_, project0_.area_id as area5_2_0_ from project project0_ where project0_.area_id in (?, ?, ?
Hibernate的检索策略
1.类级别检索 : 立即检索, 延迟检索
2.关联级别检索 : 立即检索, 延迟检索, 迫切左外连接检索
1.类级别 立即检索:
释义:指的是 在 配置文件中的class 中加入 lazy=false| true 的配置 .(默认为延迟检索:lazy=true,立即检索为 lazy=false);立即检索,只会影响 session.load 的方法 即 在加载的时候就会执行sql查询,而不是在使用对象属性的时候才执行sql查询
session.get 是不会有 sql语句的
- //立即检索: 此时不会返回 代理对象 而是立刻执行 sql语句 查询对象
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //执行上面这句 就会打印 sql语句
- }
2.类级别 延迟检索:
释义:在class 上配置 lazy=true (可以省略,默认延迟) .返回代理对象,即 只有id有值 ,其他的属性全是 null. 在hibernate运行时动态生成的扩展类,它继承了目标类,并且 在第一访问的时候才会初始化 这个代理对象
- //延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- System.out.println("部门名称:"+dept.getDeptName());
- //在执行上面这句时 才执行 sql语句 去查询,也就是第一次 (因为返回的代理对象,除id 外 其他的值都为空,所以才去查询)
- }
延迟检索下 出现的一些不同的情况
- //检索的对象不存在
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(-2));
- //执行上面不会报错
- System.out.println("部门名称:"+dept.getDeptName());
- //下面出现异常 ,因为 id为-2 的Dept不存在
- }
- //session范围内 没有访问实体对象.(Hibernate会在第一访问代理对象的时候才会初始化代理对象)
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- session.close();
- //执行上面不会报错
- System.out.println("部门名称:"+dept.getDeptName());
- //下面出现异常 ,session关闭了 代理对象没有初始化
- }
- //延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- System.out.println("部门ID:"+dept.getDeptId());
- //此时 根本就没有执行sql语句 因为 代理类 中的id 的默认值就是 我们设置的2,此时还是不会触发hibernate初始化代理实例
- session.close();
- System.out.println("部门名称:"+dept.getDeptName());
- //报错,因为 代理没有被初始化过.
- }
- //显示的初始化代理对象
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //显示的初始化代理对象
- Hibernate.initialize(dept.getDeptName());
- System.out.println("部门名称:"+dept.getDeptName());
- }
- //显示初始化后 不会报错了.
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //显示的初始化代理对象
- Hibernate.initialize(dept.getDeptName());
- session.close();
- System.out.println("部门名称:"+dept.getDeptName());
- }
- //隐式 的触发hibernate的初始化代理对象
- public void testQueryLoad1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //隐式 的触发hibernate的初始化代理对象(就是在session范围 第一次访问代理对象,此时就会触发hibernate的初始化)
- System.out.println("部门名称:"+dept.getDeptName());
- session.close();
- System.out.println("部门名称:"+dept.getDeptName());
- }
1.关联级别 立即检索:
释义:就是设置有关联的类是否立即检索(查询),在set 配置节点中 添加 lazy=false.就表示立即检索, true 就表示 延迟检索,怎么判断呢?
就从sql语句的打印中可以看出
立即检索: 在没有利用关联对象的时候,就执行了sql到数据库中将关联类给查询了一把.(是不是有点耗性能啊?)
延迟检索: 只有在你利用到关联对象的时候,才执行sql到数据库中 查询
- //类级别关联 立即检索 Dept.hbm.xml: <set name="employees" lazy=false inverse=false> ...
- public void testQueryRaload1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //这行这句话的时候 就 执行了两个sql 一个是 查询 Dept 一个是查询 Employee (立即关联执行sql)
- System.out.println("部门名称:"+dept.getDeptName());
- System.out.println("开始检索关联的员工信息");
- System.out.println("部门员工数量"+dept.getEmployees().size());
- }
1.关联级别 延迟检索:
释义:默认就是 延迟检索 lazy=true 可以省略,只有在你利用到关联对象的时候,才执行sql到数据库中 查询
- //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...
- public void testQueryRaload1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //执行这句话的时候 就 只执行一个sql 查询 dept
- System.out.println("部门名称:"+dept.getDeptName());
- System.out.println("开始检索关联的员工信息");
- System.out.println("部门员工数量"+dept.getEmployees().size());
- //执行上面的那句话之前 才执行 sql 去查询 employee
- }
//既然是延迟 是不是 又会出现 和 类级别中的延迟检索出现的一些类似特殊情况呢? 答案:是肯定的
- //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...
- //session 关闭后 关联对象没有被初始化
- public void testQueryRaload1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //执行这句话的时候 就 只执行一个sql 查询 dept
- System.out.println("部门名称:"+dept.getDeptName());
- System.out.println("开始检索关联的员工信息");
- session.close(); //session 范围内没有访问对象
- System.out.println("部门员工数量"+dept.getEmployees().size());
- //报错了,关联对象没有被初始化
- }
- //这个不会报错
- //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...
- //sesssion 关闭前 初始化关联对象
- public void testQueryRaload1(){
- Dept dept=(Dept)session.load(Dept.class,new Integer(2));
- //执行这句话的时候 就 只执行一个sql 查询 dept
- System.out.println("部门名称:"+dept.getDeptName());
- System.out.println("部门员工数量"+dept.getEmployees().size());
- System.out.println("开始检索关联的员工信息");
- session.close(); //session 范围内没有访问对象
- System.out.println("部门员工数量"+dept.getEmployees().size());
- //执行上面的那句话之前 才执行 sql 去查询 employee
- }
3.关联级别 迫切左外连接检索:
释义:将 set 节点的 out-join=true 就可以了,这个好像和 立即检索类似,只是将 原本的两个sql 变成 一个 left join 的查询 只查询了一次 只有一个sql语句
- //类关联级别 迫切左外连接查询. <set out-join="true" invers="true"
- public void testQueryOutJoin(){
- Dept dept =(Dept)session.load(Dept.class,new Integer(2));
- //执行上面代码时 ,就会执行一条 left join 的sql 查询数据库
- System.out.println("员工名称:"+dept.getDeptName());
- }