`

load方法的懒加载及原理分析

阅读更多
懒加载:

load方法与get方法的区别:
1.读取时机不同(当lazy=true的时候)
    load是采用延迟机制(load语句不读库,等使用非主键时才去读库),而get不采用延迟机制(get语句时马上读库);

2.搜索不到数据时的情况
    当搜索的数据不存在的时候,load依然会返回一个对象,在你使用该对象的非主键数据时,会抛出异常;
    当搜索的数据不存在的时候,get会返回一个null;





通过asm和cglib两个包实现;Domain是非final的。

1 session.load懒加载。

2 one-to-one(元素)懒加载:
  必须同时满足下面三个条件时才能实现懒加载(主表不能有constrained=true,所以主表没有懒加载)1)lazy!=false  2)constrainted=true  3)fetch=select

3 one-to-one(元素)懒加载:1)lazy!=false  2)fetch=select

4 many-to-many(元素):1)lazy!=false   2)fetch=select

5 many-to –many(元素):1)lazy!=false 2)fetch=select

6 懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将会出现异常。


******************************************************

1.lazy是什么
    Hibernate中的lazy(默认true)网上很多人都把它叫懒人机制,主要是告诉Hibernate获取数据时在什么时候去读库;

2.lazy的影响
    就我做的例子看来。lazy只对session.Load和获取级联信息(1对1,1对多,多对多)时起作用;

3.Session读取信息的方式(Load和级联信息)
    3.1延迟加载(lazy=true)
        当我用Load或者是该bean中有级联对象的时候,执行Load的时候并不去读库,但Load还是会返回一个对象给你,但该对象中只有主键,读库是在你使用该对象的其他属性的时候去读的;
   3.2非延迟加载(lazy=false)
        在执行Load的时候就会去把库中的数据读取出来;

4.出问题的地方
    由于我们要保证Session要及时关闭,即Load完之后,我们要执行session.close操作;但是当lazy为真的时候,在Load的时候并是直接去读库,而是等使用里面属性的时候才去读库。那么到你打印信息的时候就会报session已经被关闭的错误。
    现在你是否要问,那直接把lazy设置成false不就可以了吗?现在看下面的例子吧:

5.例子(要调用Hibernate的show_sql为真)
    5.1lazy不设置,或者设置为true的时候(Load的情况)
        5.1.1代码
          
 Session session = HibernateSessionFactory.getSession();//获取session
          Tabuser tabuser = (Tabuser) session.load(Tabuser.class, new Long(1));//获取数据
            HibernateSessionFactory.closeSession();//关闭session
          System.out.println(tabuser.getUserid());
      System.out.println(tabuser.getUsername());
       
5.1.2问题
            这时会提示第5行代码出错the owning Session was closed;
            这是由于session已经被你关闭了;
        5.1.3解决
            这时的解决办法有四种:
            a)设置class标签的lazy=false;(这种方式不推荐使用)
                b)在第三行之前加入Hibernate.initialize(tabuser);
                c)使用get方法(推荐使用这个,《get和load的区别》)
                d)使用spring(网上看到的:用filter[由于spring我还不懂,现在不讲这种方式,可能这种方式会更好])
    5.2一对多映射中set标签下lazy不设置,或者设置为true的时候(获取级联信息的情况1对多)
       5.2.1代码
          
 Session session = HibernateSessionFactory.getSession();
            Tabuser tabuser = (Tabuser) session.get(Tabuser.class, new Long(1));
          HibernateSessionFactory.closeSession();
            System.out.println(tabuser.getUserid());
            System.out.println(tabuser.getUsername());
            System.out.println(tabuser.getPostlist().iterator().next().getPostid());
        5.2.2问题
           这时第6行会报错no session or session was closed;
            这是由于session已经被你关闭了;
       5.2.3解决方法有三种:
            a)set标签下设置lazy=false;(这种方式不可行)
            b)在第三行之前加入Hibernate.initialize(tabuser.getPostlist());
            c)使用spring
        5.2.4为什么说设置lazy=false不可行
            由于你在set标签后设置lazy=false的时候,那么以后你再搜索数据的时候,Hibernate都会去获取其对应的set列表(那是否浪费掉非常多的资源,设置了这个值,可能会把整个数据库中与tabuser表有级联关系的数据全读出来[一条链子])
6.总结
    大家可以运行上面的例子,并注意观察打印信息及HQL显示的位置,即可推断出HQL是什么时候执行的

7.补充
    有涉及到延迟读取好像只有Load读取和级联信息
    如果获取信息用Query的话,则执行query.list的时候就已经读库了

代码一:  此时session没有关闭,所以正常访问
	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		User user = new User("username",12356f);
		session.save(user);
		
		User user2 = (User)session.load(User.class, 1);

		System.out.println(user2.getId());		
		System.out.println(user2.getName());
		
		tx.commit();
		session.close();
		
		
	}


代码二:此时session已经关闭,出现异常


	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		User user = new User("username",12356f);
		session.save(user);
		
		User user2 = (User)session.load(User.class, 1);

		System.out.println(user2.getId());	
		
		tx.commit();
		session.close();	
		
		System.out.println(user2.getName());
	}


代码三:利用Hibernate的initial方法初始化,session关闭后也访问正常

	public static void main(String[] args) {
		
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		User user = new User("username",12356f);
		session.save(user);
		
		User user2 = (User)session.load(User.class, 1);
		Hibernate.initialize(user2);
		System.out.println(user2.getId());	
		
		tx.commit();
		session.close();	
		
		System.out.println(user2.getName());
	}


代码四:测试代码如上,然后修改映射文件


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.hibernate.lazy">

	<class name="User" table="user" lazy="false">
		<id name="id" unsaved-value="-1">
			<generator class="native" />
		</id>
		<property name="name" />
		<property name="wage"/>
		
	</class>
</hibernate-mapping>


注意:lazy="false">

此时访问及时session关闭,那也会正常
分享到:
评论

相关推荐

    LazyLoad 图片懒加载

    首先,让我们理解懒加载的基本原理。当浏览器加载一个网页时,它会一次性下载页面上所有可见元素,包括图片。如果页面上有大量图片,这可能会导致加载时间过长。懒加载解决了这个问题,它只加载当前可视区域内的图片...

    lazy_load_tree_layui.zip

    本文将深入解析这个懒加载树组件的实现原理及应用。 一、懒加载概念与优势 懒加载,又称延迟加载,是一种优化网页性能的技术。它允许我们在用户滚动页面或需要查看某一节点时才加载相关内容,而非一次性加载所有...

    jquery.lazyload图片预加载效果 jquery预加载

    你可以下载并运行这个示例,观察预加载图片在滚动过程中的动态加载过程,更好地理解其工作原理和使用方法。 总之,jQuery LazyLoad是一个强大的图片预加载工具,通过它我们可以有效地提升网页性能,优化用户体验。...

    ViewPager的懒加载

    下面我们将深入探讨ViewPager的懒加载原理以及如何实现。 1. **ViewPager的工作原理** ViewPager通过PagerAdapter来管理页面,PagerAdapter负责创建并返回页面(通常为Fragment)。当用户滑动页面时,ViewPager会...

    jQuery图片懒加载代码

    **图片懒加载实现原理** 1. **数据属性**:首先,我们为需要懒加载的图片设置一个特殊的`data-`属性,如`data-src`,用于存储原始图片URL。 2. **监听滚动事件**:使用jQuery的`$(window).scroll()`函数监听窗口...

    图片懒加载

    为了提高页面加载速度和节省用户流量,"图片懒加载"(Lazy Load)技术应运而生。这种技术旨在延迟非可视区域内的图片加载,直到用户滚动到它们时才进行加载,从而优化网页性能。 ### 一、图片懒加载的原理 图片懒...

    关于Classloader的总结!loadClass的分析和加载细节的分析

    这篇博文主要围绕`Classloader`的`loadClass`方法进行深入探讨,并分析了类加载的细节。我们将通过以下几点来详细解析这个主题: 1. **类加载器的层次结构** Java中的类加载器通常遵循双亲委托模型。当一个类加载...

    图片延迟加载,lazyload.js使用实例

    在本文中,我们将深入探讨`lazyload.js`的工作原理、使用方法以及如何在实际项目中应用。 ### `lazyload.js`工作原理 1. **监听滚动事件**:`lazyload.js`通过监听浏览器的滚动事件,判断图片是否进入可视区域。 2...

    vue实现图片懒加载的方法分析

    本知识点将详细解析Vue中实现图片懒加载的方法,重点在于安装、配置和使用Vue-lazyload插件,以及在实际项目中的注意事项。 Vue.js图片懒加载插件的安装与初始化 首先,安装vue-lazyload插件,可以使用npm命令: ...

    IOS -(void)load 方法的响应

    了解`load`方法的工作原理和应用场景对于优化代码和提升程序性能至关重要。 1. **`load`方法的定义** `load`方法是在类的`+ (void)load`形式下定义的,它是一个类方法,意味着我们可以在类本身或其Category中声明...

    动态加载的图片LazyLoad

    动态加载,也称为延迟加载或懒加载,是一种优化网页性能的...通过查看和分析这个示例,你可以更深入地理解JQuery.LazyLoad的工作原理以及如何解决可能出现的问题。记得在本地环境中运行这个示例,以便于调试和测试。

    LazyLoad 延迟加载(按需加载)

    通过这种方法,可以显著降低首次加载页面所需的时间,同时保证用户在滚动时获得平滑的加载体验。 3. 技术实现细节: - **获取容器信息**:首先,我们需要获取包含延迟加载内容的容器的属性,如可视区域的宽度和...

    loadScript异步加载脚本函数

    #### 实现原理与代码分析 `loadScript`函数内部实现主要是通过创建一个新的`&lt;script&gt;`元素,并将其插入到DOM中来实现脚本的加载。以下为具体步骤: 1. 获取文档的`&lt;head&gt;`元素或`&lt;html&gt;`元素,以便将新创建的`...

    Python爬虫 爬取懒加载页面(以站长素材为例)

    解决这个问题的关键在于理解懒加载的工作原理。由于`requests`库在发送HTTP请求时不会模拟浏览器的行为,所以它不会触发懒加载的JavaScript。为了解决这个问题,有几种策略可以考虑: 1. **模拟浏览器**: 使用像...

    jquery lazyload延迟加载技术的实现原理分析

    《jQuery LazyLoad延迟加载技术的实现原理》 延迟加载(LazyLoad)技术是现代网页优化的重要策略之一,尤其对于图片、Flash资源、iframe以及类似FCK的网页编辑器等大容量资源,它能够显著提升页面加载速度,提高...

    lazyload.js演示页面

    开发者可以研究这些脚本来理解lazyload.js的工作原理和定制方法。 总的来说,这个压缩包提供了一个完整的延迟加载实践案例,涵盖了从HTML结构、CSS样式到JavaScript实现的全部要素,对学习和掌握lazyload.js延迟...

    Load病毒分析及处理

    【Load病毒分析及处理】 Load.exe病毒是一种对计算机系统造成潜在威胁的恶意软件,它主要通过创建特定的文件夹或文件来实现其破坏性行为。本文档将详细讲解如何在虚拟机环境中对Load.exe病毒进行分析和处理,而不...

    Objective C之计算+load方法的耗时

    首先,我们需要了解`+load`方法的工作原理。每个Objective-C类在首次被引用时,会由运行时系统加载到内存中,并依次调用该类及其所有父类的`+load`方法。由于这个过程是在应用程序启动时完成的,所以优化`+load`方法...

    Lazyload 延迟加载效果 -源码.zip

    在网页设计中,当用户滚动页面时,只加载可视区域内的内容,而将非可视区域的内容推迟到需要时再加载,这就是延迟加载,又称为懒加载。这种技术可以显著减少初始页面加载时间,提升用户体验,特别是在移动设备上,...

Global site tag (gtag.js) - Google Analytics