Hibernate中的Session.load() 和 Session.get() 的区别

文章目录

  • 相同点
  • 区别
  • 懒加载的问题

在这里插入图片描述

执行语句 session.load(UserInfoBean.class,2) 会先在一级缓存中找 id=2 的 UserInfoBean 对象(看红色线条),找不到去二级缓存找,还找不到就不找了,直接获取一个代理对象并返回该对象。当需要获取代理对象中的属性值时,则直接去数据库查(看蓝色线条),就是所谓的懒加载。

执行语句 session.get(UserInfoBean.class,2),由于 load 方法已经查过 id=2 这个对象,所以这个对象(其实是一个代理对象)已经保存在缓存中了,因此 get() 方法可以在缓存区中直接获取到这个对象(看灰色线条)。

执行语句 session.get(UserInfoBean.class,3) ,由于 id=3 这个对象没有查过,get() 方法先去一级缓存中找 id=3 的对象(看紫色线条),找不到去二级缓存找,还找不到就去数据库找。

相同点

1.两个方法均可以根据指定的实体类和 id 从数据库读取记录,并返回与之对应的实体对象。

代码如下:

session.load(Employee.class,1);
session.get(Employee.class,1);

2.两个方法都支持缓存机制,即先到一级缓存区获取数据;若没有则到二级缓存区获取数据;还是没有则访问数据库获取数据。

区别

1.如果未能发现符合条件的记录(即数据库不存在指定 id 的记录),get() 方法返回 null,而 load() 方法会抛出一个 ObjectNotFoundException。

// 对应的数据表中并不存在id=2的记录
Employee employee = session.get(Employee.class, 2);
System.out.println(employee);// null

load() 会返回的是一个实体代理对象,那么该代理对象在执行 getXxx() 时,会直接去 DB 中查找数据,如果查找不到数据,就会抛出ObjectNotFoundException 异常。

2.load() 方法支持懒加载机制(延迟加载机制),get() 不支持懒加载机制

类名.hbm.xml 配置文件 <class> 元素的 lazy 属性设置为 true 时(默认为 true),调用 load() 方法时 load() 先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理类实例(不马上到 DB 中去找),这个代理类是运行时动态生成的,是实体类的子类。该代理类实例包括原目标对象(实体对象)的所有属性和方法,该代理类实例的属性除了 ID 有值外,其它属性都是默认值。查看日志并没有 Hibernate SQL 输出,说明没有执行查询操作。当代理类实例通过 getXXX() 方法获取属性值时,Hiberante 才到 DB 中查询数据。

类名.hbm.xml 配置文件 <class> 元素的 lazy 属性设置为 false 时,调用 load() 方法与调用 get() 的效果相同,即只会返回实体类实例,并不返回代理类实例。而调用 get() 方法时不管 lazy 为何值,都直接返回实体类实例。get() 先到缓存(session缓存/二级缓存)中去查,如果没有就到 DB 中去查(即马上发出 sql)。

疑问:
当开启懒加载机制后,load() 是先去缓存区(一级/二级缓存)中查找对象,找到则返回给对象,找不到则返回一个代理对象,还是说不会去缓存区查找对象,而是直接返回代理对象呢?或者说 load() 方法首先查询session缓存,没有就创建代理对象,实际使用数据时才查询二级缓存和数据库,是这样吗?

答:
当开启懒加载机制后,load() 是先去缓存区(一级/二级缓存)中查找对象,找到则返回给对象,找不到则返回一个代理对象。
当调用代理对象的getXxx() 方法时,不会再去缓存区获取数据,而是直接访问数据库获取数据。

代理对象:
在 Hibernate 中,所谓代理对象就是依据指定的类型和给定的 ID 值(标识符值/Identifier)动态生成的虚假对象(伪对象)。该对象中除了 ID,其它属性则初始化为默认值

注意点:
get 方法如果在 session缓存中找到了指定 id 对应的对象,如果刚好该对象前面是被代理过的(如被 load 方法使用过,或者被其他关联对象延迟加载过),那么返回的还是原先的代理对象,而不是实体类对象;如果该代理对象还没有加载实体数据(就是 id 以外的其他属性数据),那么会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

懒加载的问题

Project project = session.load(Project.class, id);

如果之前没有获取过指定id的Project 对象,那么方法load() 返回的Project对象是代理类实例,里面没有数据(除了id),只有从中获取数据填充表单时才会到数据库中取数据。

如果在 ProjectDao 中调用 session.close() 关闭了 session,那么就无法取到数据。

这就出现一个矛盾:
一方面必须关闭 Session 对象,否则浪费数据库连接资源;
另一方面,当使用延迟加载机制时,又不能在DAO中直接调用 session.close() 来关闭 Session 对象。

那么如何在项目中既可以使用延迟加载机制,又能关闭 Session 对象呢?

使用 OpenSessioninView 技术,即在页面获取数据的时候 Session 还是开启的,当页面获取完数据后再关闭 Session 对象。

如何让页面获取完数据后才关闭 Session 对象呢?
1.将关闭 session 的操作写在拦截器中,等页面获取完数据后才关闭 session。
2.关闭 session 时,要找到对应的 session(要一直持有该 session)

如何一直持有同一个 Session 对象呢?
通过 ThreadLocal 来实现 Session 的线程单例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/332048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 分布式队列_〖Python〗-- Celery分布式任务队列

【Celery分布式任务队列】一、Celery介绍和基本使用Celery 是一个 基于python开发的分布式异步消息任务队列&#xff0c;通过它可以轻松的实现任务的异步处理&#xff0c; 如果你的业务场景中需要用到异步任务&#xff0c;就可以考虑使用celery&#xff0c; 举几个实例场景中可…

最大子序列和问题的解(共4种,层层推进)

【0】README 0.1&#xff09; source code and text description are from data structure and alg analysis &#xff1b; 0.2&#xff09; there are 4 methods solving maximum sum of subsequence&#xff0c; but the fourth proves to be the best one , the 3rd deser…

java设计模式代理模式_Java中的代理设计模式

java设计模式代理模式代理对象或代理对象为另一个对象提供占位符&#xff0c;以控制对该对象的访问。 代理充当原始对象的轻量级版本或简化版本。 它支持与原始对象相同的操作&#xff0c;但可以将那些请求委托给原始对象以实现它们。 代理设计模式是一种结构模式&#xff0c;…

Struts2参数值自动注入到JavaBean对象的属性中和JavaBean对象的属性值展示在页面中

文章目录参数值自动注入示例代码将JavaBean的属性值显示在页面上示例代码参数值自动注入 注意事项&#xff1a; 1.前端界面的表单项的参数命名格式为&#xff1a;Action属性名.JavaBean的属性名 2.Action的属性必须要有setter/getter方法&#xff0c;注入时会调用setter方法 …

ibmmq 通道命令_IBM MQ常用命令

常用命令创建队列管理器crtmqm –q QMgrName-q是指创建缺省的队列管理器删除队列管理器dltmqm QmgrName启动队列管理器strmqm QmgrName如果是启动默认的队列管理器&#xff0c;可以不带其名字停止队列管理器endmqm QmgrName 受控停止endmqm –i QmgrName 立即停止endmqm –p Qm…

算法运行时间中的对数

【0】README 0.1&#xff09; source code and text description are from data structure and alg analysis &#xff1b; 【1】分析算法最混乱的方面大概集中在对数上面&#xff0c; 除分治算法外&#xff0c;可将对数最常出现的规律概括为下列一般法则&#xff1a; 1.1&a…

java项目:永和大王项目_Java项目:书评

java项目:永和大王项目本文是关于这本书的 Peter Verhas撰写的Java Projects Second Edition 我去年写的 这样一篇文章的目的通常是为了促进这本书的销售。 在这种情况下没有什么不同&#xff0c;但是由于这是我写的书&#xff0c;而且我是撰写评论的人&#xff0c;因此赞美这…

Struts2+Hibernate项目中的时间和日期问题

文章目录数据表中的 datetime 的数据如何通过 json 传送给前端仅展示其日期&#xff0c;而不展示时间日期控件日期时间数据展示问题日期时间数据存储问题场景一场景二场景三场景四数据表中的 datetime 的数据如何通过 json 传送给前端仅展示其日期&#xff0c;而不展示时间 数…

把一个人的特点写具体作文_把一个人的特点写具体作文

把一个人的特点写具体作文在日常学习、工作抑或是生活中&#xff0c;大家都跟作文打过交道吧&#xff0c;写作文可以锻炼我们的独处习惯&#xff0c;让自己的心静下来&#xff0c;思考自己未来的方向。那要怎么写好作文呢&#xff1f;下面是小编为大家整理的把一个人的特点写具…

spring boot简介_Spring Boot简介

spring boot简介在本教程中&#xff0c;我们将看一下Spring Boot&#xff0c;看看它与Spring框架有何不同。 我们还将讨论Spring Boot提供的各种功能。 什么是Spring Boot&#xff1f; 在开发企业级应用程序时&#xff0c;Spring是一个功能强大的框架。 它为我们提供了诸如依赖…

C语言的运算符的优先级与结合性+ASCII表

【0】README 0.1&#xff09; 内容来源于 C程序设计语言&#xff0c; 旨在整理出C语言的运算符的优先级与结合性&#xff0c; 如下图所示&#xff08;哥子 记了大半年都没有记住&#xff0c;也是醉了&#xff0c;每次都要去翻&#xff09;&#xff1b; 0.2&#xff09; 再补充…

退货退款的售后,如何返还金币/有偿优惠券的问题

假设买家购买了3个商品&#xff0c;商品的销售价是10元&#xff0c;商品总金额是30元 买家应付金额是 30 元&#xff0c;买家使用5个金币抵扣5元&#xff0c;买家实付金额是 25 元。 后来买家退货 2 件&#xff0c;怎么退款和退币呢&#xff1f; 要将金币分摊到每个商品上&a…

python orm框架sqlalchemy_python ORM框架:SqlAlchemy

ORM,对象关系映射&#xff0c;即Object Relational Mapping的简称&#xff0c;通过ORM框架将编程语言中的对象模型与数据库的关系模型建立映射关系&#xff0c;这样做的目的&#xff1a;简化sql语言操作数据库的繁琐过程(原生sql的编写及拼接等)&#xff0c;转而直接使用对象模…

javadoc提取工具_使JavaDoc保持最新状态的工具

javadoc提取工具在许多项目中&#xff0c;文档不是最新的。 更改代码后&#xff0c;很容易忘记更改文档。 原因是可以理解的。 在代码中进行更改&#xff0c;然后进行调试&#xff0c;然后希望在测试中进行更改&#xff08;或者&#xff0c;如果您使用的是更多TDD&#xff0c;则…

栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)

【0】README 0.1&#xff09; 本文旨在总结 中缀表达式转后缀表达式并计算后缀表达式的值 的步骤&#xff0c;并给出源代码实现&#xff1b; 0.2&#xff09; 本文中涉及到的源代码均为原创&#xff0c;是对中缀转后缀和计算后缀的简单实现&#xff0c;&#xff08;旨在理清它…

用户/账户/账号的理解

文章目录用户账户账号关系用户 用户概念的理解&#xff1a; 用户就是使用者&#xff0c;可以是个人用户&#xff0c;也可以是机构用户。 账户 账户概念的理解&#xff1a; 账户&#xff0c;所谓“账”&#xff0c;就是系统根据“账”来存储和管理数据&#xff0c;类似记账…

azure 部署java_jClarity:在Azure上升级到Java

azure 部署java在互联世界公共基础设施的新时代&#xff0c;最大和最重要的两个方面是Java和OpenJDK的诞生和兴起。 因此&#xff0c;许多公司将时间和资源投入到构建最先进的技术上&#xff0c;以确保整个行业在未来几年内在AdoptOpenJDK上拥有丰富的质量&#xff0c;而且免费…

黑苹果sd卡认不出来_天生一对:新入苹果M1笔记本,DOCKCASE拓展坞弥补缺憾

2010年刚上大学那会&#xff0c;入手了人生第一台笔记本电脑&#xff0c;两边密密麻麻的各种接口&#xff0c;也没感觉到接口多少的价值&#xff1b;2016年年中入手了人生第一台苹果笔记本&#xff0c;第一次觉得电脑接口不够用&#xff1b;如今四年过去了电脑也到了更新换代的…

利用树的先序和后序遍历打印os中的目录树

【0】README0.1&#xff09;本代码均为原创&#xff0c;旨在将树的遍历应用一下下以加深印象而已&#xff1b;&#xff08;回答了学习树的遍历到底有什么用的问题&#xff1f;&#xff09;你对比下linux 中的文件树 和我的打印结果就明理了&#xff1b;0.2&#xff09;我们采用…

Hibernate常用API

文章目录删除指定的记录新增记录更新记录清空缓存将实体对象从缓存中清除将缓存中更新的数据同步到数据库把数据库中的数据刷到缓存中查询多个对象&#xff08;也就是查询多条记录&#xff09;查询指定ID的对象&#xff08;查询指定ID值的记录&#xff09;参考删除指定的记录 U…