Hibernate的加载方式——GET与LOAD的对比

2023-10-27

      在Hibernate框架中,最常用到的加载方式就非Get和Load莫属了,然而Get和Load在加载方式上边还有很多的不同,下面让我们来分析一下他们的不同之处。


区别

       从返回的结果上来看,get、load在检索到数据的时候,会返回对象(代理对象或实体对象),但他们的检索方式不同,这个后续在细说。get检索不到数据的时候,会返回null;而load检索不到数据会返回org.hibernate.ObjectNotFoundException。下面通过两个例子来分析一下get与load的工作原理。


工作原理

Get加载(数据库中存在检索的数据),这里只分析测试类,实体类就不再讨论了。

/**
 * 查询数据库中有数据的字段
 */
public void testGetNotNull() {
	Session session = null;
	try {
		session = HibernateUtils.getSession();
		session.beginTransaction();
		// 数据库中存在id为2的数据
		User user = (User)session.get(User.class, 2);
		System.out.println("---------Get加载--------");
		System.out.println(user);
		System.out.println(user.getId() + "---->>" + user.getName());
		System.out.println("------------------------");
		session.getTransaction().commit();
	} catch (Exception e) {
		e.printStackTrace();
		session.getTransaction().rollback();
	} finally {
		HibernateUtils.closeSession(session);
	}
}


       因为Hibernate规定get方法不能使用延迟加载,当执行到User user = (User)session.get(User.class, 2);这条语句时,get方法首先会查询session缓存,没有的话就查询二级缓存,最后会查询数据库,因此在执行该语句的时候,会先发出sql语句进行查询。而且,执行get方法的时候,get方法每次都会从数据库直接查询。由于这是数据库中存在id为2的数据,因此,user会返回实体对象。如下图:



Get加载(数据库中不存在检索的数据)

/**
 * 查询数据库中不存在的数据
 */
public void testGetWithNull() {
	Session session = null;
	try {
		session = HibernateUtils.getSession();
		session.beginTransaction();
		// 数据库中不存在id为0的数据
		User user = (User)session.get(User.class, 0);
		System.out.println("---------Get加载--------");
		System.out.println(user);
		//System.out.println(user.getId() + "---->>" + user.getName());
		System.out.println("------------------------");
		session.getTransaction().commit();
	} catch (Exception e) {
		e.printStackTrace();
		session.getTransaction().rollback();
	} finally {
		HibernateUtils.closeSession(session);
	}
}


      同上,在执行到User user = (User)session.get(User.class, 0);这条语句时,get方法每次都是直接查询数据库,在执行该语句时,Hibernate会发出sql语句,到数据库进行查询数据,由于id为0的数据不存在,get方法查询不到数据时,会返回null。因此,user的结果自然也是null了。如下图:


Load加载(数据库中存在检索的数据)

/**
 * 数据库中存在查询的数据
 */
public void testLoadNotNull() {
	Session session = null;
	try {
		session = HibernateUtils.getSession();
		session.beginTransaction();
		// 数据库中存在id为2的数据
		User user = (User)session.load(User.class, 2);
		System.out.println("----------Load加载-----------");
		System.out.println(user);
		System.out.println(user.getId() + "---->>" + user.getName());
		System.out.println("-----------------------------");
		session.getTransaction().commit();
	} catch (Exception e) {
		e.printStackTrace();
		session.getTransaction().rollback();
	} finally {
		HibernateUtils.closeSession(session);
	}
}
    Hibernate中,load方法是支持延迟加载的,在执行到User user = (User)session.load(User.class, 2);这条语句时,load方法首先会查找session的persistent Context中是否存在缓存,如果存在则直接返回;如果没有缓存,则load方法会判断是否是lazy加载,如果不是lazy方式,则直接访问数据库,查询Id为2的数据,由于数据库中存在Id为2的数据,因此get方法会返回实体对象。
 如果load方法判断的是lazy方式加载,那么就需要建立代理对象,对象的initialized属性为false,target属性为null,在访问获得的代理对象的属性时,会访问数据库,找到记录后就会把该记录的对象复制到代理对象的target上,并将initialized属性设为true。在这个例子中,load方法采用的是lazy方式,因此在执行load方法时,Hibernate不会发出sql语句,因为此时Hibernate建立了代理对象,但并没有访问代理对象的属性。当执行System.out.println(user);时,Hibernate才会初次发出sql语句,去查询数据库。如下图:

Load加载(数据库中不存在检索的数据)

/**
 * 数据库中不存在查询的数据
 */
public void testLoadWithNull() {
	Session session = null;
	try {
		session = HibernateUtils.getSession();
		session.beginTransaction();
		// 数据库中不存在id为0的数据
		User user = (User)session.load(User.class, 0);
		System.out.println("----------Load加载-----------");
		System.out.println(user);
		//System.out.println(user.getId() + "---->>" + user.getName());
		System.out.println("-----------------------------");
		session.getTransaction().commit();
	} catch (Exception e) {
		e.printStackTrace();
		session.getTransaction().rollback();
	} finally {
		HibernateUtils.closeSession(session);
	}
}
    同上,在执行到load方法时,load方法会首先查询session中是否存在缓存,如果存在则直接返回,如果不存在则会判断是否为lazy,这里设置的是lazy方式,因此load方法会认为数据库中存在数据,直接建立代理对象,把代理对象返回给user。
    而执行到System.out.println(user);时,Hibernate会发出sql语句,访问数据库查询Id为0的数据,由于数据库中不存在Id为0的数据,因此load方法会返回org.hibernate.ObjectNotFoundException,直接抛出异常。如下图:

结束语

     Hibernate中,对于get和load方法的根本区别,就在于Hibernate对于load方法认为数据库中一定存在要检索的数据,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,那么只能抛出异常;而对于get方法,Hibernate一定要获取到真实的数据才会返回对象,否则返回null。
参考资料:
后勤仓库的Hibernate get和load区别

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate的加载方式——GET与LOAD的对比 的相关文章

  • 断点续传:大文件分片上传

    有时用户上传下载文件需要历时数小时 万一线路中断 不具备断点续传的方式就只能从头重传 断点续传方式允许用户从上传下载断线的地方继续传送 这样大大减少了用户的烦恼 分片上传 就是将所要上传的文件 按照一定的大小 将整个文件分隔成多个数据块 我
  • Nginx重中之重的知识点

    1 反向代理 proxy pass http baidu com location proxy pass http atcui com 代理服务器的概念 代理服务器 客户机在发送请求时 不会直接发送给目的主机 而是先发送给代理服务器 代理服
  • 架构、框架、设计模式三者的区别

    架构 框架 设计模式 对于搞IT的人来说 再熟悉不过了 那么它们三者有什么联系 又有什么区别呢 架构 架构是几个动词 是一个方法论 包含一系列活动过程和步骤 可以联想一下架构师 大数据架构师 软件架构师 首席架构师等等 他们的工作职责 就是
  • JAVA代码实现抖音转载视频无水印视频,亲测通过

    许多小伙伴想做抖音视频 无奈没有摄影器材 也没有取景材料 就想着去用别人人气视频来提高自己的粉丝量 可问题又来了 别人的视频通过分享 或者链接根本不是原创 上面还带着水印 视频一挂上去就被发现了 小则视频不通过 给出警告 大则封号 降低视频
  • Git基本介绍

    一 Git简介 Git是一个版本控制的工具 我们可以把每天的工作代码放到Git上 同时Git的特点是分布式的 可以搭建集群 以保证一个Git宕机 导致数据丢失 可以实现本地提交 避免网络问题造成不可使用的状况 SVN和Git的区别 1 SV
  • Java 两点经纬度计算距离和角度

    角度 计算两点对于正北方向的朝向角度 0 360 param start format latitude 30 longitude 120 param end private static double bearing List
  • springboot集成Druid之后报错:discard long time none received connection. , jdbcUrl:jdbc:mysql://lo

    整合druid的配置 在pom xml中
  • 佛祖保佑,永无bug——springboot项目启动图案的修改方法

    在resources目录 与application yml文件同级目录 下创建banner txt文件 将下面的代码复制进去就好了 AnsiColor BRIGHT YELLOW ooOoo o8888888o
  • 在运行jar包时如何替换jar内变量的值?

    在运行jar包时如何替换jar内变量的值 举个例子 1 问题描述 java程序中定义了变量String vars System getProperty aa String vars1 System getProperty aa test 把
  • Excel文件读取和生成_模板方法模式&建造者模式&反射

    一 需求说明 系统中经常有读取各种不同表头excel的需求 如根据用户上传的数据来实现某种功能的批量操作 我们通常会根据读取的内容把数据放入不同的实体中 形成List
  • java在注解中绑定方法参数的解决方案

    我们有这样子的需求 需要记录用户操作某个方法的信息并记录到日志里面 例如 用户在保存和更新任务的时候 我们需要记录下用户的ip 具体是保存还是更新 调用的是哪个方法 保存和更新的任务名称以及操作是否成功 这里最好的技术就是spring ao
  • dll、so库转Java代码

    dll so库转Java代码 下载jar JNA代码生成 参数说明 生成的maven项目代码结构如下 众所周知 java程序如果要调用动态库 so dll 的函数 最传统方式是使用JNI技术 用JNI写java调用接口代码是非常痛苦的 调试
  • 安装Windows子系统(WSL2)-Ubuntu

    参考资料 https docs microsoft com zh cn windows wsl install manual https blog csdn net qq 28412779 article details 113565257
  • Java复习:IO流

    File类的使用 IO流原理及流的分类 1 I O是Input Output的缩写 I O技术是非常实用的技术 用于 处理设备之间的数据传输 如读 写文件 网络通讯等 2 Java程序中 对于数据的输入 输出操作以 流 stream 的 方
  • Alibaba Druid简单介绍及使用

    文章目录 概要 Druid 的主要特点和功能 Druid 的使用 一 添加依赖 二 配置数据源 三 配置 Druid 监控和过滤器 四 启动应用程序 五 访问监控页面 小结 概要 Alibaba Druid 以下简称 Druid 是阿里巴巴
  • JavaSE的复习:Java基本语法

    1 变量 变量的分类 按数据类型 对于每一种数据都定义了明确的具体数据类型 强类型语言 在内存中分配了不同大小的内存空间 弱类型语言则不用明确指明数据类型 例如js var 变量的分类 按声明的位置的不同 在方法体外 类体内声明的变量称为成
  • 【Javadoc生成开发文档(Terminal或IDEA中)】

    Javadoc生成开发文档 一 Javadoc工具介绍 二 常用标记 三 使用方式 四 生成文档的两种方式 1 Terminal方式 2 IDE方式 一 Javadoc工具介绍 大家在查看官网文档的时候 会不会感慨人家的帮助文档写的真有逻辑
  • bootstrap使用之stickUp(固定导航栏)

    1 stickUp是jQuery下的一个导航栏插件 当界面较长时 导航栏会固定在顶部 不会移动 如下图 2 废话少说 下载http www bootcss com p stickup 在里面有示例文档 只是注意看index的时候js写在下面
  • SOFA Boot 整合SOFA RPC 、SOFA Registry

    参考资料 https www wenjiangs com doc dc7xvpxh https www sofastack tech projects sofa rpc getting started with rpc SOFA Stack
  • Mac系统安装Tomcat、创建Java Web项目并配置Tomcat作为服务器

    mac安装Tomcat tomcat下载链接 https tomcat apache org download 80 cgi 解压 访问http localhost 8080 出现如下页面 说明tomcat启动成功 启动成功之后 记得先执行

随机推荐

  • 【实践2】Python openpyxl获取Excel所有表名,删除Excel内指定工作表(判断是否存在某个sheet,存在即删除)

    简单介绍 定时爬虫任务会有每天使用pandas将数据写入Excel表中的动作 但每天写入的行数会有不同 例如第一天写入5000行而第二天只写入3000行 会导致该表中前3000行是最新数据 后2000是前一天的数据 因此最好的方法是在将数据
  • Magento关于添加Robots.txt文件

    在 Magento和其他电子商务平台的SEO话题中 有一个很常见的问题 怎样写robots txt文件 里面到底应该包含哪些内容 为了很好滴回答这个问题 我将根据我所有的知识和经验尝试找出一个最佳的robots txt文件写法 下面部分ro
  • 时间SQL查询大全

    查询15天之前得数据 modifydate 是数据库得时间字段格式yyyy MM dd hh mm ss SELECT FROM 表名 where DATE SUB CURDATE INTERVAL 15 DAY gt date modif
  • mysql数据库升级-MySQL 5.7.25主备架构小版本In-Place升级思路

    一 描述 漏扫发现MySQL有低风险漏洞 自己写方案 自己做测试 自己升级 版本 MySQL 5 7 25 升级到MySQL 5 7 28最新版本 架构 主从架构 二 升级流程 1 下载最新版数据库软件MySQL 5 7 28 2 上传到指
  • 萌新的Arduino大作业

    全自动收 晾衣服机 备注 本人因学校社团假期作业要求 用Arduino IDE编写并模拟实现了一个全自动 收 凉衣服的机器 由于硬件条件不足只能模拟 本人也是萌新一枚 希望观看的 大佬们不喜勿喷 有发现做错的话欢迎在评论区讨论 如果对你有帮
  • 西门子编程基础学习分享(3)-数据类型详述

    1200PLC的数据类型详述 前文所提到的数据类型用于描述数据的长度以及属性 即为指定数据元素的大小以及如何解释数据 每个指令至少支持一种数据类型 因而指令上使用的操作数的数据类型必须与指令所支持的数据类型一致 所以在设计程序 建立变量时需
  • Uva 540 Team Queue

    有t个团体的人正在排一个长队 每次新来一个人时 如果这个成员所在的团体已经有人在排队了 那么他就加到最后一个队友身后 如果整个大队列中没有他的团体 那么他就要排在整个大队列的最后 输入每个团队的人数 每个人的编号 要求支持下面的操作 前两种
  • 【订单服务】库存解锁和关单

    消息队列流程图 监听库存解锁 下单成功 库存锁定成功 接下来的业务调用失败 导致订单回滚 之前锁定的库存就要自动解锁 配置队列和交换机 Configuration public class MyRabbitConfig 使用json序列化机
  • 失业在家靠做PPT日赚800-1000元,有一门副业真的很重要!

    下班做PPT 半年挣8万是什么感觉 你好 我是佳佳 一个用PPT兼职挣钱的宝妈 我现在每天抽2个小时 坐在电脑前 把各种素材像拼图一样拼接一下 像这样 然后把成稿投稿到设计平台 就能挣到钱 你是不是觉得 我是个职业设计师 挺厉害的 不是的
  • NLP(十五)让模型来告诉你文本中的时间

    背景介绍 在文章NLP入门 十一 从文本中提取时间 中 笔者演示了如何利用分词 词性标注的方法从文本中获取时间 当时的想法比较简单快捷 只是利用了词性标注这个功能而已 因此 在某些地方 时间的识别效果并不太好 比如以下的两个例子 原文1 苏
  • python递归实现字符串逆反

    def main string input Enter a string string1 reverse string print string s reverse format is string1 def reverse string
  • YOLOV7学习记录之训练过程

    在前面学习YOLOV7的过程中 我们已经学习了其网络结构 然而实际上YOLOV7项目的难点并不在于其网络模型而是在于其损失函数的设计 即如何才能训练出来合适的bbox 神经网络模型都有训练和测试 推理 过程 在YOLOV7的训练过程中 包含
  • Java学习笔记:Java中的加号“+”

    在今晚学习Java时惊奇地发现Java中有 System out println 赋值后c的值为 c 这样的与c语言不同的语法 本着打破砂锅问到底 xue dao si 的精神 稍微整理了一下 下面是整理出来的Java中加号 的用法 算术运
  • mysql字段使用非int做主键,查询时候使用整型和字符串做查询条件的区别

    where条件key是整型的时候也可以找到记录 但是效率慢 不会使用索引 使用字符串的时候会使用主键索引会很快
  • ionic入门教程第十五课-ionic性能优化之图片延时加载

    周五的时候有个朋友让我写一个关于图片延时加载的教程 直到今天才有空编辑 这阶段真的是很忙 公众号都变成僵尸号了 实在是对不起大家 有人喜欢我的教程 可能我总习惯了用比较简单容易理解的方式去描述这些东西 别的就不多说了 大家遇到什么问题 可以
  • 100天精通Python(基础篇)——第23天:while循环 :99乘法表

    i 0 while i lt 10 print 我喜欢你 i 1 print endl i 0 sum 0 while i lt 101 i 1 sum i print f sum sum import random num random
  • django1.10 静态文件配置

    settings配置 网站引用静态文件时都会加上该地址 如 http www xxx com static css mini css STATIC URL static 静态文件根目录 执行命令 python manage py colle
  • PostgreSQL 服务启动不了问题

    配置了postgresql数据的配置文件 pg hba conf后 重记一下服务 结果启动不了 提 示错误 root instance 609xznso run systemctl start postgresql 11 Job for p
  • C++11 function、bind、可变参数模板

    在设计回调函数的时候 无可避免地会接触到可回调对象 在C 11中 提供了std function和 std bind两个方法来对可回调对象进行统一和封装 C 语言中有几种可调用对象 函数 函数指针 lambda表达式 bind创建的对象以及
  • Hibernate的加载方式——GET与LOAD的对比

    在Hibernate框架中 最常用到的加载方式就非Get和Load莫属了 然而Get和Load在加载方式上边还有很多的不同 下面让我们来分析一下他们的不同之处 区别 从返回的结果上来看 get load在检索到数据的时候 会返回对象 代理对