lazy fetch

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语句的 

Java代码   收藏代码
  1. //立即检索: 此时不会返回 代理对象 而是立刻执行 sql语句 查询对象  
  2.     public void testQueryLoad1(){  
  3.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  4.                 //执行上面这句 就会打印 sql语句  
  5.     }  



2.类级别 延迟检索: 
释义:在class 上配置 lazy=true (可以省略,默认延迟) .返回代理对象,即 只有id有值 ,其他的属性全是 null. 在hibernate运行时动态生成的扩展类,它继承了目标类,并且  在第一访问的时候才会初始化 这个代理对象 

Java代码   收藏代码
  1. //延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象  
  2.     public void testQueryLoad1(){  
  3.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  4.           
  5.         System.out.println("部门名称:"+dept.getDeptName());  
  6.         //在执行上面这句时 才执行 sql语句 去查询,也就是第一次 (因为返回的代理对象,除id 外 其他的值都为空,所以才去查询)  
  7.     }  


延迟检索下 出现的一些不同的情况 

Java代码   收藏代码
  1.        //检索的对象不存在  
  2. public void testQueryLoad1(){  
  3.     Dept dept=(Dept)session.load(Dept.class,new Integer(-2));  
  4.                //执行上面不会报错  
  5.     System.out.println("部门名称:"+dept.getDeptName());  
  6.     //下面出现异常 ,因为 id为-2 的Dept不存在   
  7. }  
  8.       //session范围内 没有访问实体对象.(Hibernate会在第一访问代理对象的时候才会初始化代理对象)  
  9.      public void testQueryLoad1(){  
  10.     Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  11.     session.close();  
  12.                //执行上面不会报错  
  13.     System.out.println("部门名称:"+dept.getDeptName());  
  14.     //下面出现异常 ,session关闭了 代理对象没有初始化  
  15. }  
  16.   
  17.   
  18.       //延迟检索 会返回代理对象 不会立刻执行 sql语句 查询对象  
  19. public void testQueryLoad1(){  
  20.     Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  21.       
  22.     System.out.println("部门ID:"+dept.getDeptId());  
  23.     //此时 根本就没有执行sql语句 因为 代理类 中的id 的默认值就是 我们设置的2,此时还是不会触发hibernate初始化代理实例  
  24.               session.close();  
  25.               System.out.println("部门名称:"+dept.getDeptName());  
  26.                //报错,因为 代理没有被初始化过.  
  27.                  
  28. }  
  29.   
  30.      //显示的初始化代理对象  
  31.       public void testQueryLoad1(){  
  32.     Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  33.     //显示的初始化代理对象      
  34.     Hibernate.initialize(dept.getDeptName());  
  35.       
  36.     System.out.println("部门名称:"+dept.getDeptName());  
  37.       
  38. }  
  39.   
  40.        //显示初始化后  不会报错了.  
  41.       public void testQueryLoad1(){  
  42.     Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  43.     //显示的初始化代理对象      
  44.     Hibernate.initialize(dept.getDeptName());  
  45.     session.close();  
  46.     System.out.println("部门名称:"+dept.getDeptName());  
  47.       
  48. }  
  49.   
  50.        //隐式 的触发hibernate的初始化代理对象  
  51.        public void testQueryLoad1(){  
  52.     Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  53.      //隐式 的触发hibernate的初始化代理对象(就是在session范围 第一次访问代理对象,此时就会触发hibernate的初始化)   
  54.     System.out.println("部门名称:"+dept.getDeptName());  
  55.     session.close();  
  56.     System.out.println("部门名称:"+dept.getDeptName());  
  57.       
  58. }  
  59.        



1.关联级别 立即检索: 
释义:就是设置有关联的类是否立即检索(查询),在set 配置节点中 添加 lazy=false.就表示立即检索, true 就表示 延迟检索,怎么判断呢? 
就从sql语句的打印中可以看出 
  立即检索: 在没有利用关联对象的时候,就执行了sql到数据库中将关联类给查询了一把.(是不是有点耗性能啊?) 
  延迟检索: 只有在你利用到关联对象的时候,才执行sql到数据库中 查询 

Java代码   收藏代码
  1. //类级别关联 立即检索 Dept.hbm.xml: <set name="employees" lazy=false inverse=false> ...   
  2.     public void testQueryRaload1(){  
  3.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  4.         //这行这句话的时候  就 执行了两个sql 一个是 查询 Dept 一个是查询 Employee  (立即关联执行sql)  
  5.         System.out.println("部门名称:"+dept.getDeptName());  
  6.         System.out.println("开始检索关联的员工信息");  
  7.         System.out.println("部门员工数量"+dept.getEmployees().size());  
  8.     }  



1.关联级别 延迟检索: 
释义:默认就是 延迟检索 lazy=true 可以省略,只有在你利用到关联对象的时候,才执行sql到数据库中 查询 

Java代码   收藏代码
  1. //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
  2.     public void testQueryRaload1(){  
  3.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  4.         //执行这句话的时候  就 只执行一个sql 查询 dept  
  5.         System.out.println("部门名称:"+dept.getDeptName());  
  6.         System.out.println("开始检索关联的员工信息");  
  7.         System.out.println("部门员工数量"+dept.getEmployees().size());  
  8.         //执行上面的那句话之前  才执行 sql 去查询 employee   
  9.     }  



//既然是延迟 是不是 又会出现 和 类级别中的延迟检索出现的一些类似特殊情况呢? 答案:是肯定的 

Java代码   收藏代码
  1. //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
  2.         //session 关闭后 关联对象没有被初始化   
  3.     public void testQueryRaload1(){  
  4.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  5.         //执行这句话的时候  就 只执行一个sql 查询 dept  
  6.         System.out.println("部门名称:"+dept.getDeptName());  
  7.         System.out.println("开始检索关联的员工信息");  
  8.         session.close(); //session 范围内没有访问对象  
  9.         System.out.println("部门员工数量"+dept.getEmployees().size());  
  10.                   
  11.         //报错了,关联对象没有被初始化  
  12.     }  
  13.   
  14. //这个不会报错  
  15. //类级别关联 延迟检索 Dept.hbm.xml: <set lazy=true inverse=false> ...   
  16.     //sesssion 关闭前 初始化关联对象  
  17.     public void testQueryRaload1(){  
  18.         Dept dept=(Dept)session.load(Dept.class,new Integer(2));  
  19.         //执行这句话的时候  就 只执行一个sql 查询 dept  
  20.         System.out.println("部门名称:"+dept.getDeptName());  
  21.         System.out.println("部门员工数量"+dept.getEmployees().size());  
  22.         System.out.println("开始检索关联的员工信息");  
  23.         session.close(); //session 范围内没有访问对象  
  24.         System.out.println("部门员工数量"+dept.getEmployees().size());  
  25.         //执行上面的那句话之前  才执行 sql 去查询 employee   
  26.     }  



3.关联级别 迫切左外连接检索: 
释义:将 set 节点的 out-join=true  就可以了,这个好像和 立即检索类似,只是将 原本的两个sql 变成 一个 left join 的查询   只查询了一次 只有一个sql语句 

Java代码   收藏代码
    1. //类关联级别  迫切左外连接查询. <set out-join="true" invers="true"  
    2. public void testQueryOutJoin(){  
    3.     Dept dept =(Dept)session.load(Dept.class,new Integer(2));  
    4.     //执行上面代码时 ,就会执行一条  left join 的sql 查询数据库   
    5.     System.out.println("员工名称:"+dept.getDeptName());  
    6.       


<think>好的,我现在需要回答用户关于“lazy loading or lazy evaluation in programming”的问题。用户还提到之前引用了Hibernate中的Eager和Lazy Fetch类型的比较,所以需要结合这些内容。 首先,我要明确什么是懒加载(Lazy Loading)和惰性求值(Lazy Evaluation)。这两个概念都属于延迟处理的技术,但应用场景不同。懒加载通常用于数据加载,比如数据库访问,而惰性求值多用于函数式编程中的表达式计算。 接下来,我需要分点解释这两个概念。先讲懒加载,举Hibernate的例子,说明Eager和Lazy的区别,引用用户提供的资料[^1]。然后转到惰性求值,举编程语言的例子,比如Haskell或Python的生成器。 还要注意用户的系统级指令,比如数学公式需要用$...$格式,如果有的话。不过这个问题可能不涉及数学公式,但需要检查是否有需要的地方,比如算法复杂度分析时可能需要使用大O符号,如$O(n)$。 用户要求生成相关问题,我需要根据内容提出三个相关问题,放在最后。同时回答结构要清晰,分步骤解释,并确保引用正确。 现在组织内容:首先定义懒加载,说明其优缺点和应用场景,引用Hibernate的例子。然后定义惰性求值,举例子,比如Python生成器和Haskell的无限列表。接着比较两者的异同,最后总结应用场景和注意事项。 需要确保使用中文,避免使用Markdown格式,代码块用三个反引号包裹。同时检查LaTeX语法是否正确,如果有的话。例如,在提到算法复杂度时,用$O(n)$这样的格式。 最后生成相关问题,比如懒加载的优缺点,惰性求值的实现方式,两者的比较等。</think>在编程中,**懒加载(Lazy Loading)**和**惰性求值(Lazy Evaluation)**是两种延迟处理的优化技术,但应用场景和实现方式有所不同。 --- ### 1. 懒加载(Lazy Loading) **定义**:懒加载是一种仅在需要时才加载数据的策略,常用于减少资源消耗(如数据库查询、内存占用)。 **典型应用**: - **数据库关联查询**:在Hibernate中,通过设置`FetchType.LAZY`,关联实体(如用户的所有订单)不会立即加载,直到代码显式访问该属性时才触发查询[^1]。 - **前端资源加载**:如图片的延迟加载(当图片进入可视区域时再加载)。 **代码示例**(Hibernate实体映射): ```java @Entity public class User { @OneToMany(fetch = FetchType.LAZY) // 懒加载用户的订单 private List<Order> orders; } ``` **优缺点**: - **优点**:减少初始加载时间和内存占用。 - **缺点**:可能因延迟加载引发“N+1查询问题”(需通过JOIN FETCH或批量查询优化)。 --- ### 2. 惰性求值(Lazy Evaluation) **定义**:惰性求值是函数式编程中的概念,指表达式不会立即计算,直到其值被实际使用时才求值。 **典型应用**: - **生成器(Generators)**:如Python的生成器表达式`(x*2 for x in range(10))`仅在迭代时生成值。 - **无限序列**:Haskell中可定义无限列表`[1..]`,但仅计算需要的部分。 **代码示例**(Python生成器): ```python def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b # 仅计算前10项 fib = fibonacci() print([next(fib) for _ in range(10)]) # 输出:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34] ``` **优缺点**: - **优点**:节省计算资源,支持无限数据结构。 - **缺点**:调试困难,可能导致不可预测的性能问题。 --- ### 3. 懒加载 vs 惰性求值的核心区别 | 特性 | 懒加载 | 惰性求值 | |---------------------|-------------------------|-----------------------| | **应用领域** | 数据加载(如ORM、前端) | 计算过程(如函数式编程) | | **触发时机** | 显式访问时触发 | 隐式使用时触发 | | **典型问题** | N+1查询 | 副作用管理 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值