美文网首页
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属性

    lazy概念: 只有真正使用该对象时,才会创建,对于hibernate而言,正真使用的时候才会发出sql语句,只对...

  • Swift中的属性

    1、属性访问控制2、属性观察3、KVO4、lazy修饰符和lazy方法 1、属性访问控制 对于方法来说比较直接,我...

  • iOS Lazy 的详细使用

    1 Lazy 只被调用一次计算。 2 Lazy 里不要包含变量属性。

  • kotlin—lazy及其原理

    1、lazy简介 lazy是属性委托的一种,是有kotlin标准库实现。它是属性懒加载的一种实现方式,在对属性使用...

  • lombok 文档翻译

    @Getter 可选元素: 使用示例: 说明: Lazy:默认为:false,如果设置 lazy 则 该属性必须为...

  • 从源码角度分析 Kotlin by lazy 的实现

    by lazy 的作用 延迟属性(lazy properties) 是 Kotlin 标准库中的标准委托之一,可以...

  • 从源码角度分析 Kotlin by lazy 的实现

    by lazy 的作用 延迟属性(lazy properties) 是 Kotlin 标准库中的标准委托之一,可以...

  • 08-属性

    属性 存储属性 计算属性 注:不能只有set 枚举rawValue原理 延迟存储属性(Lazy Stored Pr...

  • Swift延迟存储属性(Lazy)

    延迟存储属性(Lazy) 用Lazy修饰的存储属性 延迟存储实行必须有一个默认的初始值 延迟存储属性在第一次访问的...

  • Kotlin中的延迟属性(lazy properties)

    属于Kotlin中的委托属性这一章中的标准委托 延迟属性Lazy lazy() 是接受一个lambda 并返回一个...

网友评论

      本文标题:Lazy属性

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