Hibernate(Spring Data)抓取策略

文章目录

  • 示例代码放到最后,使用的是Springboot 项目
  • 1. 简介
  • 2. Hibernate抓取策略分类
    • 2.1 即时加载(Eager Loading)
    • 2.2 延迟加载(Lazy Loading)
    • 2.3 子查询加载(Subselect Loading)
    • 2.4 基于批处理的加载(Batch Loading)
  • 3. 即时加载(Eager Loading)
    • 3.1 概述
    • 3.2 实体类映射配置
    • 3.3 使用场景和注意事项
  • 4. 延迟加载(Lazy Loading)
    • 4.1 概述
    • 4.2 实体类映射配置
    • 4.3 使用场景和注意事项
  • 5. 子查询加载(Subselect Loading)
    • 5.1 概述
    • 5.2 实体类映射配置
    • 5.3 使用场景和注意事项
  • 6. 基于批处理的加载(Batch Loading)
    • 6.1 概述
    • 6.2 实体类映射配置
    • 6.3 使用场景和注意事项
  • 7. 总结
  • Demo

示例代码放到最后,使用的是Springboot 项目

1. 简介

本文将深入讨论Hibernate中的抓取策略,介绍不同类型的抓取策略以及它们的使用场景和注意事项。

2. Hibernate抓取策略分类

2.1 即时加载(Eager Loading)

即时加载是指在查询主实体时立即加载相关联的实体对象。这种策略会在查询时一次性加载所有关联的实体对象,可以减少数据库查询次数。

2.2 延迟加载(Lazy Loading)

延迟加载是指在访问关联属性时才会真正加载相关的实体对象。这种策略在查询主实体时只会加载主实体对象,而关联的实体对象只有在被访问时才会被加载。

2.3 子查询加载(Subselect Loading)

子查询加载是指通过执行子查询来加载关联的实体集合对象,而不是通过单独的SQL语句执行关联查询。这种策略适用于一对多或多对多关系,并可以提高性能。

2.4 基于批处理的加载(Batch Loading)

基于批处理的加载是指通过执行批量SQL语句一次性加载多个实体对象。这种策略可以减少数据库交互次数,提高性能。

3. 即时加载(Eager Loading)

3.1 概述

即时加载策略可以通过设置@ManyToOne@OneToOne等注解来实现,默认情况下Hibernate会使用即时加载进行关联对象的加载。

3.2 实体类映射配置

在关联属性上使用fetch = FetchType.EAGER注解来指定即时加载策略。

@Entity
@Data
public class Classes {@Idprivate int id;private String name;@OneToMany(mappedBy = "classes", fetch = FetchType.EAGER)private List<Student> students;
}

这里可以看到查询的班级实体种student属性集合有二十个对象
在这里插入图片描述

3.3 使用场景和注意事项

  • 适用于关联实体对象数据量较小且经常被使用的情况。
  • 频繁加载大量关联对象可能导致性能问题,需要谨慎使用。

4. 延迟加载(Lazy Loading)

4.1 概述

延迟加载策略可以通过设置@ManyToOne@OneToOne等注解来实现,默认情况下Hibernate会使用延迟加载进行关联对象的加载。

4.2 实体类映射配置

在关联属性上使用fetch = FetchType.LAZY注解来指定延迟加载策略。

@Entity
public class Classes{// ...@OneToMany(mappedBy = "classes", fetch = FetchType.LAZY)private List<Student> students;// ...
}

这里开启懒加载后查询到的对象种数据是空的,只有当执行get方法时才会去获取数据
在这里插入图片描述

在这里插入图片描述

4.3 使用场景和注意事项

  • 适用于关联实体对象数据量较大或者不经常被使用的情况,可以减少不必要的数据库查询。
  • 注意检查在延迟加载策略下可能引发的懒加载异常,需要合理处理。

5. 子查询加载(Subselect Loading)

5.1 概述

子查询加载策略通过执行子查询来加载关联的实体集合对象,适用于一对多或多对多关系。

5.2 实体类映射配置

在关联集合属性上使用@Fetch注解,并指定@Fetch(FetchMode.SUBSELECT)来启用子查询加载策略。

@Entity
public class Order {// ...@OneToMany(mappedBy = "order")@Fetch(FetchMode.SUBSELECT)private List<OrderItem> orderItems;// ...
}

5.3 使用场景和注意事项

  • 适用于一对多或多对多的关联关系,减少关联集合对象的查询次数,提高性能。
  • 子查询加载策略会执行多条SQL语句,需要考虑数据库性能和查询效率的平衡。

6. 基于批处理的加载(Batch Loading)

6.1 概述

基于批处理的加载策略通过执行批量SQL语句一次性加载多个实体对象,减少数据库交互次数,提高性能。

6.2 实体类映射配置

在关联集合属性上使用@BatchSize注解,并指定要批量加载的大小。

@Entity
public class Order {// ...@OneToMany(mappedBy = "order")@BatchSize(size = 10)private List<OrderItem> orderItems;// ...
}

@BatchSize 注解的作用是为了优化 Hibernate 对关联集合属性的查询性能。它可以应用于实体类的集合属性上,告诉 Hibernate 在加载该集合属性时一次性加载指定个数的数据,从而减少数据库查询次数。

具体来说,@BatchSize 注解会影响到使用延迟加载(FetchType.LAZY)的关联集合属性的时候。当访问该集合属性时,如果该属性还没有被初始化,Hibernate 会触发查询加载数据。通过设置 @BatchSize 注解,可以控制同时加载的数据量,从而减少数据库查询的次数。

例如,假设我们有一个 EntityA 实体类,其中包含一个 List<EntityB> 类型的集合属性,我们可以在该属性上添加 @BatchSize 注解来优化查询性能:

@Entity
public class EntityA {// ...@OneToMany(mappedBy = "entityA", fetch = FetchType.LAZY)@BatchSize(size = 10) // 在这里添加注解private List<EntityB> entityBList;// getters and setters
}

在这个例子中,将 @BatchSize(size = 10) 注解应用于 entityBList 属性上。当访问 entityBList 属性时,Hibernate 会一次性加载 10 条 EntityB 数据,从而减少查询次数,提高性能。

需要注意的是,@BatchSize 注解只对延迟加载的集合属性有效,对于即时加载(FetchType.EAGER)的集合属性无效。此外,它只影响到关联集合属性本身的加载,不会影响到关联实体对象的加载。

总结来说,@BatchSize 注解可以优化延迟加载的关联集合属性的查询性能,通过一次加载多个数据项减少数据库查询次数。但需要根据具体情况选择合适的批处理大小,并综合考虑内存消耗和查询性能。

6.3 使用场景和注意事项

  • 适用于一对多或多对多的关联关系,减少数据库交互次数,提高性能。
  • 需要根据实际情况调整批量加载的大小,避免一次性加载过多数据导致内存占用过大。

7. 总结

Hibernate提供了多种抓取策略用于加载关联实体对象,包括即时加载、延迟加载、手动加载、子查询加载和基于批处理的加载。选择合适的抓取策略可以提高查询性能和减少数据库交互次数,但需要根据实际情况和性能要求进行综合考虑。

Demo

import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.List;
@Entity
@Data
public class Classes {@Idprivate int id;private String name;
//	@OneToMany(mappedBy = "classes")
//	private List<Student> students;//子查询加载
//	@OneToMany(mappedBy = "classes")
//	@Fetch(FetchMode.SUBSELECT)
//	private List<Student> students;//基于批处理的加载@OneToMany(mappedBy = "classes")@BatchSize(size = 6)private List<Student> students;public void loadCustomer() {// 手动加载关联的Customer对象Hibernate.initialize(students);}}import lombok.Data;
import javax.persistence.*;@Entity
@Data
public class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;private String name;@ManyToOne(fetch = FetchType.EAGER)private Classes classes;}
public interface JPAClassesDao extends JpaRepository<Classes, Integer>, Serializable {
}
public interface JPAStudentDao extends JpaRepository<Student, Integer> , Serializable {
}
@AutowiredJPAStudentDao jpastudentDao;@AutowiredJPAClassesDao jpaclassesDao;
//    @Resource
//    private  SessionFactory factory;@RequestMapping("/Insert")public void InsertClassesTest(){List<Classes> a=new ArrayList<>();List<Student> s=new ArrayList<>();for (int i = 0; i < 10; i++) {Classes b=new Classes();b.setId(i);b.setName("班级"+i);a.add(b);for (int j = 0; j < 20; j++) {Student c=new Student();c.setClasses(b);c.setName("学生"+i+j);s.add(c);}}jpaclassesDao.saveAll(a);jpastudentDao.saveAll(s);}@RequestMapping("/QueryEAGER")public void queryEAGERTest(){Classes byId = jpaclassesDao.findById(0).get();for (Student student : byId.getStudents()) {System.out.println("班级"+byId.getName()+"的:"+student.getName());}}@RequestMapping("/QueryLAZY")public void queryLAZYTest(){Classes byId = jpaclassesDao.getOne(1);System.out.println("--------------------------------------");for (Student student : byId.getStudents()) {System.out.println("班级"+byId.getName()+"的:"+student.getName());}}@RequestMapping("/QueryTriggerLAZY")public void queryTriggerTest(){Classes byId = jpaclassesDao.getOne(1);// byId.loadCustomer();for (Student student : byId.getStudents()) {System.out.println("班级"+byId.getName()+"的:"+student.getName());}}@RequestMapping("/QuerySubselect")public void querySubselectTest(){Classes byId = jpaclassesDao.getOne(1);for (Student student : byId.getStudents()) {System.out.println("班级"+byId.getName()+"的:"+student.getName());}}
        <!-- hibernate依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>

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

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

相关文章

Nginx 配置记录-未完!

目的 Nginx和前端后端的关系都是密不可分的&#xff0c;但是它的配置又是很多的&#xff0c;我们有一些不常用的&#xff0c;所以我们要总结下来&#xff0c;这里我们提供一个样例&#xff0c;每次有新的配置&#xff0c;就先修改样例&#xff0c;让我们有迹可循&#xff0c;看…

使用spring自带的发布订阅来实现发布订阅

背景 公司的项目以前代码里面有存在使用spring自带发布订阅的代码&#xff0c;因此稍微学习一下如何使用&#xff0c;并了解一下这种实现方式的优缺点。 优点 实现方便&#xff0c;代码方面基本只需要定义消息体和消费者&#xff0c;适用于小型应用程序。不依赖外部中间件&a…

1992-2022年全国31省市产业升级、产业结构高级化水平面板数据(含原始数据和计算过程)

1992-2022年全国31省市产业升级、产业结构高级化水平面板数据&#xff08;含原始数据和计算过程&#xff09; 1、时间&#xff1a;1992-2022年 2、指标&#xff1a;地区生产总值、第一产业增加值、第二产业增加值、第三产业增加值、第一产业占GDP比重、第二产业占GDP比重、第…

windows下docker compose方式挂载数据卷volume遇到的问题

例子一&#xff0c;windows 下docker desk top部署TDengine td-compose.yml version: 3 services:tdengine1:image: tdengine/tdengine:latestcontainer_name: tdengine1hostname: tdengine1ports:- 6030:6030- 6041:6041- 6043-6049:6043-6049- 6043-6049:6043-6049/udpresta…

Excel·VBA二维数组组合函数、组合求和

目录 1&#xff0c;二维数组组合函数举例 2&#xff0c;组合求和 之前的文章《ExcelVBA数组组合函数、组合求和》和《ExcelVBA数组排列函数》&#xff0c;都是针对一维数组的组合和排列 二维数组组合&#xff1a;对一个m行*n列的二维数组&#xff0c;每行抽取1个元素进行组合&a…

java.nio.ByteBuffer 学习笔记

目录 java 重复使用bytebuffer例子&#xff1a; java验证flip函数&#xff1a; flip讲解 以下内容转自&#xff1a; java.nio.ByteBuffer java 重复使用bytebuffer例子&#xff1a; import java.nio.ByteBuffer;public class ByteBufferExample {public static void main…

PyCharm切换虚拟环境

PyCharm切换虚拟环境 为了满足不同任务需要不同版本的包&#xff0c;可以在Anaconda或者Miniconda创建多个虚拟环境文件夹&#xff0c;并在PyCharm下切换虚拟环境。 解决方案 1、打开Ananconda Prompt 2、创建自己的虚拟环境 格式&#xff1a;conda create -n 虚拟环境名字…

部署你自己的导航站-dashy

现在每天要访问的网页都太多了&#xff0c;尽管chrome非常好用&#xff0c;有强大的标签系统。但是总觉的少了点什么。 今天我就来分享一个开源的导航网站系统 dashy。这是一个国外的大佬的开源项目 github地址如下&#xff1a;https://github.com/Lissy93/dashy 来简单说一下…

数据结构--树4.2.4(树、森林即二叉树的相互转换(仅供参考))

目录 一、树转换成二叉树步骤 二、森林转换成二叉树 三、二叉树到树、森林的转换 一、树转换成二叉树步骤 分两个步骤&#xff1a; 1、在树中所有的兄弟结点之间加一连线。 2、对每个结点&#xff0c;除了保留与其长子&#xff08;最左边&#xff09;的连线外&#xff0c;去…

机器学习和数据挖掘02-Gaussian Naive Bayes

概念 贝叶斯定理&#xff1a; 贝叶斯定理是概率中的基本定理&#xff0c;描述了如何根据更多证据或信息更新假设的概率。在分类的上下文中&#xff0c;它用于计算给定特征集的类别的后验概率。 特征独立性假设&#xff1a; 高斯朴素贝叶斯中的“朴素”假设是&#xff0c;给定…

西北大学计算机考研844经验分享(初试科目844-详细复习方法)

个人介绍 ​ 我本科就读于西安某双非一本计算机科学与技术专业&#xff0c;在2022年进行了半年的考研复习&#xff0c;从2022年6月开始陆陆续续复习&#xff0c;复习6个多月&#xff0c;上岸西北大学软件工程专业研究生&#xff0c;专业课分数129分。在读研一年来&#xff0c;…

android studio安装教程

1、android studio 下载 下载网址&#xff1a;Download Android Studio & App Tools - Android Developers 2、开始安装 因为不需要每次连接手机进行调试&#xff0c;android studio给我们提供了模拟器调试环境。 一般选择自定义安装&#xff0c;这样可选sdk以及下载路径…

安全移动设备TEE认证

安全之安全(security)博客目录导读 TEE之GP(Global Platform)认证汇总 目录

Rust 的四大类型的宏 (元编程)

文章目录 概念函数宏或声明宏&#xff08;Function Macro&#xff09;过程宏&#xff08;Procedural Macro&#xff09;类函数的过程宏&#xff08;Function-like-procedural-macros&#xff09;派生宏&#xff08;Derive Macro&#xff09;派生宏附加其他属性 属性宏&#xff…

@Async引发的循环依赖问题

这个以前分析过了&#xff0c;但是再看的时候感觉写的太乱了(流水账)&#xff0c;这个是精简版本。 bug复现 先上bug&#xff0c;众所周知&#xff0c;spring通过实例化和属性注入分开解决了循环依赖&#xff0c;理论上也不会有问题。但是意外就那么来了&#xff0c;经过排查是…

CI/CD 持续集成 持续交付

CI&#xff08;Continuous integration&#xff09;持续集成 参考&#xff1a;https://www.jianshu.com/p/2132949ff84a 持续集成是指多名开发者在开发不同功能代码的过程当中&#xff0c;可以频繁的将代码行合并到一起并切相互不影响工作。 持续集成的目的&#xff0c;是让…

操作符算数转换题

目录 1.交换两个变量&#xff08;不创建临时变量&#xff09; 2.统计二进制中1的个数 3.打印整数二进制的奇数位和偶数位 4.求两个数二进制中不同位的个数 5.【一维数组】有序序列合并 6.获得月份天数 7.变种水仙花数 8.选择题总结tips 这篇博文主要分享操作符&算…

ChatGPT:引领人机交互的未来

前言 在信息技术飞速发展的时代&#xff0c;人机交互的方式也在不断演进。技术对人们生活和工作的影响。本文将带您深入探讨一款引领人机交互未来的人工智能模型——ChatGPT。 ChatGPT简介 ChatGPT 是一种由开放AI&#xff08;OpenAI&#xff09;开发的人工智能模型&#xf…

WIndows 配置多版本python环境,非常清晰明了

配置多个python环境 下面以配置三个python版本环境为例子 首先下载好三个环境的python&#xff0c;如&#xff1a;python2.7、python3.6、python3.10 给个官网链接自己下&#xff0c;想要几版本就下几&#xff1a;https://www.python.org/downloads/windows/ 下载完成后将pyth…

C语言控制语句——跳转关键字

循环和switch专属的跳转&#xff1a;break循环专属的跳转&#xff1a;continue无条件跳转&#xff1a;goto break 循环的break说明 某一条件满足时&#xff0c;不再执行循环体中后续重复的代码&#xff0c;并退出循环 需求&#xff1a;一共吃5碗饭, 吃到第3碗吃饱了, 结束吃饭…