Hibernate懒加载解析

简介:

Hibernate懒加载解析

在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,这时Hibernate用懒加载机制来弥补这种缺陷,但是这只是弥补而不是用了懒加载总体性能就提高了。

我们所说的懒加载也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库。

   实现懒加载的前提: 

1 实体类不能是final的

2 能实现懒加载的对象都是被CGLIB(反射调用)改写的代理对象,所以不能是final修饰的
3 须要asm,cglib两个jar包
4 相应的lazy属性为true
5 相应的fetch属性为select 
下面几种可以实现懒加载功能:

1、   通过Session.load()实现懒加载

load(Object, Serializable):根据id查询 。查询返回的是代理对象,不会立刻访问数据库,是懒加载的。当真正去使用对象的时候才会访问数据库。

用load()的时候会发现不会打印出查询语句,而使用get()的时候会打印出查询语句。

使用load()时如果在session关闭之后再查询此对象,会报异常:could not initialize proxy - no Session。处理办法:在session关闭之前初始化一下查询出来的对象:Hibernate.initialize(user);

使用load()可以提高效率,因为刚开始的时候并没有查询数据库。但很少使用。

2、   one-to-one(元素)实现了懒加载。

在一对一的时候,查询主对象时默认不是懒加载。即:查询主对象的时候也会把从对象查询出来。

需要把主对象配制成lazy="true" constrained="true"  fetch="select"。此时查询主对象的时候就不会查询从对象,从而实现了懒加载。

一对一的时候,查询从对象的是默认是懒加载。即:查询从对象的时候不会把主对象查询出来。而是查询出来的是主对象的代理对象。

3、   many-to-one(元素)实现了懒加载。

多对一的时候,查询主对象时默认是懒加载。即:查询主对象的时候不会把从对象查询出来。

多对一的时候,查询从对象时默认是懒加载。即:查询从对象的时候不会把主对象查询出来。

hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy="proxy".具体设置成什么要看你的需求,并不是说哪个设置就是最好的。在<many-to-one>与<one-to-one>标签上:当为true时,会有懒加载特性,当为false时会产生N+1问题,比如一个学生对应一个班级,用一条SQL查出10个学生,当访问学生的班级属性时Hibernate会再产生10条SQL分别查出每个学生对应的班级.

lazy= 什么时候捉取

fetch= 捉取方式:select=关联查询;join=连接表的方式查询(效率高)

fetch=join时,lazy的设置将没有意义.

4、   one-to-many(元素)懒加载:默认会懒加载,这是必须的,是重常用的。

一对多的时候,查询主对象时默认是懒加载。即:查询主对象的时候不会把从对象查询出来。

一对多的时候,查询从对象时默认是懒加载。即:查询从对象的时候不会把主对象查询出来。

需要配置主对象中的set集合lazy="false" 这样就配置成是不懒加载了。或者配置抓取方式fetch="join"也可以变成不懒加载。 

实现懒加载的方案:

方法一:(没有使用懒加载)  

用 Hibernate.initialize(de.getEmps()) 提前加载一下. 
方法二:

把与Session脱离的对象重新绑定

lock()方法是用来让应用程序把一个未修改的对象重新关联到新session的方法。

//直接重新关联

session.lock(fritz,LockMode.NONE);

//进行版本检查后关联

session.lock(izi,LockMode.READ);

//使用SELECT... FOR UPDATE进行版本检查后关联

session.lock(pk,LockMode.UPGRADE);

方法三:

OpenSessionInView

参见 http://www.javaeye.com/topic/32001          

fetch 和 lazy 配置用于数据的查询 

lazy 参数值常见有 false 和 true,Hibernate3映射文件中默认lazy = true ;

fetch 指定了关联对象抓取的方式,参数值常见是select和join,默认是select,select方式先查询主对象,再根据关联外键,每一个对象发一个 select查询,获取关联的对象,形成了n+1次查询;而join方式,是leftouter join查询,主对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询。 

在映射文件中,不同的组合会使用不同的查询: 

1、lazy="true" fetch = "select" ,使用延迟策略,开始只查询出主对象,关联对象不会查询,只有当用到的时候才会发出sql语句去查询 ;

2、lazy="false" fetch = "select" ,没有用延迟策略,同时查询出主对象和关联对象,产生1+n条sql. 

3、lazy="true"或lazy="false"fetch = "join",延迟都不会作用,因为采用的是外连接查询,同时把主对象和关联对象都查询出来了. 

另 外,在hql查询中,配置文件中设置的join方式是不起作用的,而在其他查询方式如get、criteria等是有效的,使用 select方式;除非在hql中指定join fetch某个关联对象。fetch策略用于get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。

相关文章
|
存储 算法
halcon模板匹配实践(1)算子参数说明与算子简介
halcon模板匹配实践(1)算子参数说明与算子简介
1133 0
|
3月前
智谱发布GLM-4.5V,全球开源多模态推理新标杆,Day0推理微调实战教程到!
视觉语言大模型(VLM)已经成为智能系统的关键基石。随着真实世界的智能任务越来越复杂,VLM模型也亟需在基本的多模态感知之外,逐渐增强复杂任务中的推理能力,提升自身的准确性、全面性和智能化程度,使得复杂问题解决、长上下文理解、多模态智能体等智能任务成为可能。
666 0
|
缓存 关系型数据库 PostgreSQL
PostgreSQL relcache在长连接应用中的内存霸占"坑"
除了常见的执行计划缓存、数据缓存,PostgreSQL为了提高生成执行计划的效率,还提供了catalog, relation等缓存机制。PostgreSQL 9.5支持的缓存如下 ll src/backend/utils/cache/ attoptcache.c catcache.c
7807 0
|
8月前
|
Kubernetes API 网络安全
当node节点kubectl 命令无法连接到 Kubernetes API 服务器
当Node节点上的 `kubectl`无法连接到Kubernetes API服务器时,可以通过以上步骤逐步排查和解决问题。首先确保网络连接正常,验证 `kubeconfig`文件配置正确,检查API服务器和Node节点的状态,最后排除防火墙或网络策略的干扰,并通过重启服务恢复正常连接。通过这些措施,可以有效解决与Kubernetes API服务器通信的常见问题,从而保障集群的正常运行。
639 17
|
XML JSON Java
万字SpringBoot学习笔记|菜鸟版
Spring Boot是Pivotal团队在Spring的基础上提供的一套全新的开源框架,其目的是为了简化Spring应用的搭建和开发过程。Spring Boot去除了大量的XML配置文件,简化了复杂的依赖管理。 官网地址:spring.io/projects/sp… Spring Boot入门 简介 Spring Boot是简化Spring应用开发的一个框架、整个Spring技术栈的一个大整合(Spring全家桶时代)、J2EE开发的一站式解决方案(Spring Cloud是分布式整体解决方案)。 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Serv
387 0
|
JavaScript 开发工具 数据安全/隐私保护
npm包【详解】(内含npm包的开发、发布、安装、更新、搜索、卸载、查看、版本号更新规则、package.json详解等)
npm包【详解】(内含npm包的开发、发布、安装、更新、搜索、卸载、查看、版本号更新规则、package.json详解等)
387 0
|
前端开发 Java
CompletableFuture的高级用法与实战
【4月更文挑战第20天】
722 1
|
Java Maven Spring
使用Proguard混淆Spring Boot项目代码
使用Proguard混淆Spring Boot项目代码
5197 0
|
运维 数据可视化 Devops
IT团队提升业务认知的5个秘诀|云效BizDevOps主题系列
践行 BizDevOps ,科技更需要向前一步,与业务并肩作战。 在业务认知上的三个层次包括理解业务基本面、解读业务策略变化、提议数字化方案。 5 个有效秘诀包括: a.形成简版的业务基本面知识条目,设为基线,进行考试。 b.翻转课堂, IT 团队通过业务反串讲来习得业务知识。 c.定期进行业务知识擂台赛,加速业务策略变为显性知识的螺旋。 d.将组织中的提案逻辑模板化,通过专项的刻意训练,让 IT 团队能够自如地进行数字化提案。 e.定期进行共创提案会,找到“四两拨千斤”的数字化的举措,创造价值。
9045 2
IT团队提升业务认知的5个秘诀|云效BizDevOps主题系列
|
缓存 网络协议 前端开发
Http实战之无状态协议、keep-alive分析(2)
Http实战之无状态协议、keep-alive分析(2)
713 1
Http实战之无状态协议、keep-alive分析(2)