美文网首页
Lazy属性

Lazy属性

作者: Mango_lxh | 来源:发表于2018-09-11 19:30 被阅读0次

    lazy概念:

    只有真正使用该对象时,才会创建,对于hibernate而言,正真使用的时候才会发出sql语句,只对加载有效

    hibernate lazy策略可以使用在:
    * <class>标签上,可以取值:true/false( hibernate 3.x 代理默认打开)
    * <property>标签上,可以取值:true/false需要类增强工具
    * <set><list>标签上,可以取值:true/false/extra
    * <one-to-one><many-to-one>单端关联上,可以取值:false/proxy/noproxy
    Lazy的实现:
    hibernate采用第三方的CGLIB库,它可以对我们的类生成代理类(控制原对象,并对原对象的功能进行增强)它继承原先的类,生成一个子类作为一个代理类,当真正调用代理类上的方法时,它会看一看目标对象是否加载,如果没加载它才会真正的访问。

    1、类上的懒加载

    • 默认开启,只对普通属性有效
    • load支持类上的懒加载,但前提必须是懒加载开启
    class上的Lazy策略例:

    例:hibernate_lazy_for_class

    • <class>标签上,可以取值:true/false( hibernate 3.x 代理默认打开)
    • <class>标签上的lazy特性只对普通属性起作用
    • hibernate支持lazy策略只有在session打开状态下有效
      System.out.println("group.name=" + group.getName());
      //不能正确输出,抛出LazyInitializationException 异常,因为session已经关闭(session线程不安全)
      //hibernate支持lazy策略只有在session打开状态下有效

    解决方法:
    每个线程绑定自己的session,用到懒加载拦截器和ThreadLocal技术

    解决懒加载的技术

    配置openSessionInview拦截器,一直开启session 直到对象都输出完成

    如何把当前线程绑定到session上?

    采用ThreadLocal里的set方法,把当前线程作为key,传过来的session作为value

    懒加载拦截器
        <filter>
       <filter-name>hibernateFilter</filter-name><filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        </filter>
    

    ThreadLocal的原理

    ThreadLocal类主要由四个方法组成:initialValue(),get(),set(T),remove()
    在ThreadLocal类中有一个线程安全的Map,用于存储每一个线程的变量的副本。
    这个map在同一时刻只能有一个线程访问

    public class ThreadLocal
    {
    private Map values = Collections.synchronizedMap(new HashMap());;//线程安全
    // set方法—设置当前线程的局部变量
    public void set(Object newValue) {
    //key是当前线程
    values.put(Thread.currentThread(), newValue);
    }
    //get方法—返回当前线程的局部变量
    public Object get() {
    Thread curThread = Thread.currentThread();
    Object o=values.get(currentThread);
    //判断Map中是否包含这样的key
    if (o == null && !values.containsKey(curThread))
    { o = initialValue();
    values.put(curThread, o);
    }
    return o;
    }
     // initialValue方法—返回当前线程的局部变量的初始值
    protected Object initialValue()
    { return null;
    }
    // remove方法—移除当前线程的局部变量
    public void remove() {
    //通过key将键值对删除
    values.remove(Thread.currentThread());
    } 
    }
    

    说明:当线程处于活动状态时它会持有该线程的局部变量的引用,当该线程运行结束后,该线程拥有的局部变量都会结束生命周期。

    2、集合上的懒加载

    只适用于one to many和many to many
    类上的懒加载不会影响集合上的懒加载
    可以取值:true/false/extra

    (1)类上的懒加载true,集合上的懒加载true
    (2)类上懒加载开启,集合上的懒加载关闭
    (3)都关闭
    (4)类关闭,集合开启。
    (5)类开启。集合extra。

    extra发sql语句更智能,效率高
    extra和true的区别:如果为true,那么查找集合里的元素个数时,会查找数据库里的所有记录,生成对象设置到set集合,而extra只查找有多少记录,并不会把记录生成对象设置到set集合

    3、单端上的懒加载
    只用在one to one和many to one 上,指定一的一端如何加载
    可以取值:false/proxy/noproxy
    默认的取值是proxy

    指定一的一方如何加载
    有三种方式完成懒加载

    相关文章

      网友评论

          本文标题:Lazy属性

          本文链接:https://www.haomeiwen.com/subject/rheugftx.html