1、延迟加载,也叫懒加载,它是Hibernate为提高程序执行效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
2、Hibernate中主要是通过代理(proxy)机制来实现延迟加载。它的具体过程:Hibernate从数据库获取某一个对象数据时,或获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用到该对象的数据,hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,这样在某些情况下,就可以提高查询效率。
有如下程序代码:
User user = (User) session.load(clazz, id); // 直接返回的是代理对象
System.out.println(user.getId()); // 没有发送sql语句到数据库加载
user.getName(); // 创建真实的User实例,并发送sql语句到数据库中
注意:
1、不能判断User = null;代理对象不可能为空
代理对象的限制:和代理关联的session对象,如果session关闭后访问代理则抛异常。session关闭之前访问数据库
2、getId()方法不行因为参数为ID,getClass()方法不用访问数据库就可以得到的数据
Hibernate中默认采用延迟加载的情况主要有以下几种
1、当调用session上的load()加载一个实体时,会采用延迟加载。
2、当session加载某个实体时,会对这个实体中的集合属性值采用延迟加载。
3、当session加载某个实体时,会对这个实体所有单端关联的另一个实体对象采用延迟加载。
当实体中存在另一个实体对象的时候,延迟加载决定了抓取方式:当为Lazy加载时,在一个session中,如果不访问实体中的实体对象属性,hibernate就不会级联查询内部实体,当为EAGER的时候,hibernate会在查询实体的时候,级联查询实体内部的其他实体对象。
延迟加载也称为懒加载,是Hibernate3关联关系对象默认的加载方式,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。简单理解为,只有在使用的时候,才会发出sql语句进行查询。
延迟加载的有效期是在session打开的情况下,当session关闭后,会报异常。当调用load方法加载对象时,返回代理对象,等到真正用到对象的内容时才发出sql语句。
回顾事务:
事务:首先应该理解这个词在SQL里面是什么意思。
事务:就是一组简单的逻辑单元,事务的四个特性:原子性、一致性、隔离性、持久性。
事务的分类:显示、隐式、自动提交。
事务的创建:开始事务:begin transcation
提交事务:commit transaction
回滚事务:rollback transaction
非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。
Hibernate提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。
这个过程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个Hibernate会话要在对象使用的时候一直开着。
提高效率,主要是对属性(在数据库中存在相应的表)进行延迟加载(load),在第一次查询的时候,只查询当前的表,当用到延迟加载的对象时(非延迟加载会查询所有关联属性的表),会先从缓存中去找延迟加载的对象(如果session已经关闭,会抛出SessionClosedException),如果对象已经在缓存中,则直接从缓存获取,如果对象不在缓存中,则进入数据库查找,所以,延迟加载是为了提高效率,如果在hibernate映射文件lazy设置成false,用load则和用get效果一样。
延时加载是指:不是一开始就创建对象,而是当要调用的时候才去创建对象。
延时加载不是问题,是为了解决问题,在hibernate中,有两种关系是相对存在的,就是一对多和多对一,如果同时使用这两种关系,并且不使用延迟加载会很麻烦的。
比如:学生和班级的关系。
学生实体里应该存在一个班级实体,班级实体里应该存在学生集合。
如果使用急切加载,那么在查询学生的时候需要查出班级,而班级又需要查询学生集合,而每个学生又需要班级实体……如此反复,直到内存崩溃。