1.立即检索和延迟检索(懒加载)
立即检索: 立即加载检索方法指定的对象
延迟检索: 延迟加载检索方法指定的对象
增强延迟: 极其懒惰,只查询需要的,不会查询别的(lazy=extra)<class name=”cn.itcast.Customer” table=”customers” lazy=”true”>
* class元素lazy=true: 为延迟加载
* class元素lazy=false: 为立即检索
代码演示:
Customer customer = (Customer)session.load(Customer.class,1); // 如果lazy=false,那么当执行到这个位置产生select语句
System.out.println(“*********”);
customer.getAge(); // 如果lazy=true, 那么当执行到这个位置才产生select语句
为什么要使用延迟检索???
在hibernate中,当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限,为了减少系统资源的消耗,这时我们可以使用hibernate
懒加载机制来缓解这种缺陷.所谓的懒加载,就是它在查询的时候不会立刻访问数据库,而是返回代理兑现,当真正去使用对象的时候才会访问数据库注意: 不管lazy的值是true还是false, session.get()方法和query.list()方法永远是立即检索
使用懒加载的目的: 提高性能,不要总是和数据库打交道!!!
2.延迟检索中的代理
* 只有延迟检索才会产生代理对象
* hibernate会为产生的代理对象分配一个OID,但其他的属性不分配值,此时还没有查询
Customer c=(Customer)session.load(Customer.class, 1);
System.out.println(c.getClass()); // 代理对象
c.getClass(); // hibernate不会执行select语句
c.getId(); // hibernate不会执行select语句
c.getAge(); // 该行hibernate会执行select语句
if(!Hibernate.isInitialized(c)){
Hibernate.initialize(c); // 初始化代理对象, hibernate执行select查询
}
3.类级别和关联级别
* 查询Customer对象
Customer c = (Customer) session.load(Customer.class,1); -- 类级别
* 查询Customer对象对应的订单集合c.getOrders() -- 关联级别
* 如果fetch的值为join lazy=”true/false/extra”,使用get方法查询Customer关联的订单集合,总是使用迫切左外连接
* 如果fetch的值为join lazy=”true/false/extra”,* lazy=”false” 立即检索客户关联的订单集合
* lazy=”true” 延迟检索客户关联到的订单集合
* lazy=”extra” 增强延迟检索客户关联到订单集合(要什么查什么)
5.多对一关联的检索策略
* <many-to-one> 元素也有一个lazy属性和fetch属性 <many-to-one fetch=”join” lazy=”false”>
fetch=”join”
* 如果使用get方式检索, lazy=”false/proxy/no-proxy” 总是使用迫切左外连接检索
* 如果使用query方式检索:
* lazy=”false” 这时不再采用左外连接检索,而是采用立即检索, 先查询订单,再通过订单的表的外键id查询客户
fetch=”select”
* lazy=”false” 立即检索(先查询订单,再通过订单的外键查询客户)
* lazy=”proxy”
* 对端的class元素中的lazy=”false”,立即检索
<class name=”cn.itcast.Customer” table=”customers” lazy=”false”>
* 对端的class元素中的lazy=”true”,延迟检索
<class name=”cn.itcast.Customer” table=”customers” lazy=”true”>
6. get和load方法区别
相同点: 都是通过id查询对象
不同点:
如果id在数据库中不存在,get返回null, load抛出异常
get方法总是立即加载(不管配置的lazy=false还是lazy=true),
load可以配置延迟和立即两种load查询,返回不是一个javaBean对象,而是一个javaBean对象的代理Proxy,
那我们何时使用Load???
一般情况下,如果一个表很少修改且确定此条记录存在的情况下, 才可以使用load.