您的位置:首页 > 数据库

Hibernate性能优化 --- 延迟加载(懒加载)

2011-12-14 12:14 281 查看
                                                                                                  
Hibernate性能优化 --- 延迟加载(懒加载)

一  延迟加载概述

    Hibernate中主要是通过代理机制来实现延迟加载的。

目的:为了减少和数据库交互的次数,推迟和数据库交互的时间

过程:Hibernate从数据库获取某一个对象时,获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据,Hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值,只有在真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据,在某种情况下,可以提高查询效率。

二 实例使用:

1.session.load()

public static User getUser(int id) {
       Session session = null;
       try {
           session = HibernateUtil.getSession();
           Class clazz = User.class;
           User user = (User) session.load(clazz, id);  
           //强迫用户初始化,在什么时候使用的时候即可调用数据库
           Hibernate.initialize(user);
           return user;
       } finally {
           // 使资源得到释放
           if (session != null) {
              session.close();
           }
       }
    }

说明:

(1)懒加载load()在运行后没有立刻访问相应的数据库,返回的是代理对象,通过new关键字创建一个代理对象 User_$$_javassist_7类,它是User的一个子类,是User动态创建的,所以强制造型没有错,是为了使代理对象不冲突。
(2)懒加载是通过代理对象实现的,代理对象比domain功能要强大,是domain类对象的子类,代理对象返回的是从数据库中查找到的,而不是代理对象的查找的是domain中的属性。
(3)代理对象永远不可能为空,所以判空无意义。
(4)代理对象的使用是有限制的:必须是在和代理对象关联的session关闭之前使用
    (5)当确实需要这个用户的数据时,才会访问数据库

    (6)Hibernate.initialize()是初始化是强迫使用User对象
(7)当在懒加载之后,调用getID()不会有输出,没有查询数据库的操作,因为id值已经传过来了。getClass()和getId()一样,不用操作数据库就可以得到
 
2.集合的关联的懒加载
(1)一对一的关联
    当在查主对象person的时候,将Person和IdCard左外连接查询出来person对象和idCard对象,没有懒加载,原因是对性能没有什么提高
    当在查从对象idCard的时候,对于idCard所关联的person对象是懒加载的。当在主方法中调用的时候,会抛异常,可以在得到从对象之后,初始化从对象的主对象就可以,用的语句是:
Hibernate.initialize(idCard.getPerson());也可以在idCard的映射文件中取消懒加载,即lazy=”false”;
 
一对一的关联满足懒加载的条件:
(1)主表不能有constrained=true,所以主表没有懒加载 
(2)从表中lazy!=false
(3)fetch=select  是缺省的值
 
(2)一对多的关联
    Department department = (Department) session.get(Department.class,depId);
    上面一句话当现实执行的sql语句时,输出的语句是一条查询depart的语句,而没有输出Employee的查询语句,是因为employee的信息放到了代理对象的集合属性中,如果把懒加载的功能取消了,在查询的时候会把员工的信息也查询出来,而在不需要员工的时候也会查询出来,这样不会提高Hibernate的工作效率。
注:
//输出的是代理对象
System.out.println(department.getEmps().getClass());
 
(3)多对一的关联
    在一的一方,相当于获取到Employee,查询的只是employee的信息,而部门的信息是放到代理对象中的,但是员工只能属于一个部门,所以用不用懒加载是没什么关系的,相当于是一对一中的影响不是很大。
 
(4)lazy和fetch介绍
lazy是指相关联的属性什么时候抓取
fetch通过什么方式来进行抓取,fecth=”join”时,会把两条select连接成一条语句,lzay属性不起作用
    如果抓取策略改为join的话,懒加载就会取消。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息