Hibernate(Spring Data)抓取策略

news2024/11/18 20:16:26

文章目录

  • 示例代码放到最后,使用的是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 {
	@Id
	private 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 {
	@Id
	private 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 {
}



    @Autowired
    JPAStudentDao jpastudentDao;
    @Autowired
    JPAClassesDao 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.coloradmin.cn/o/956137.html

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

相关文章

【100天精通python】Day48:python Web开发_WSGI接口与使用

目录 1 WSGI接口 1.1 CGI 简介 1.2 WSGI 简介 1.3 定义 WSGI 接口 1.3.1 应用程序&#xff08;Application&#xff09; 1.3.2 服务器&#xff08;Server&#xff09; 1.4 WSGI 接口的使用示例 1.5 WSGI接口的优势 1 WSGI接口 上一节实现了静态服务器&#xff0c;但是当…

Cell子刊:肠道菌菌株之间的“明争暗斗”

抗生素耐药性质粒可以在肠道中不同肠杆菌科之间传播。本期经典文献解读&#xff0c;为大家带来发表在Cell Host and Microbe上的研究成果&#xff0c;探索具有相似营养需求的肠杆菌科沙门氏菌群如何在同一肠道中共同繁殖及质粒转移。 期刊&#xff1a;Cell Host Microbe …

八、MySQL(DML)如何修改表中的数据?

1、修改表数据 &#xff08;1&#xff09;基础语法&#xff1a; update 表名 SET 字段名1数值1,字段名2数值2&#xff0c;…… [where 条件]; &#xff08;2&#xff09; 操作实例&#xff1a; 第一步&#xff1a; 先准备一张表 insert into things values (10086,18,0x12…

spark支持深度学习批量推理

背景 在数据量较大的业务场景中&#xff0c;spark在数据处理、传统机器学习训练、 深度学习相关业务&#xff0c;能取得较明显的效率提升。 本篇围绕spark大数据背景下的推理&#xff0c;介绍一些优雅的使用方式。 spark适用场景 大数据量自定义方法处理、类sql处理传统机器…

掌握Kubernetes API:释放容器编排的潜力

Kubernetes API使用 1、 API是什么&#xff1f; API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;&#xff1a; 是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或指软件系统不同组成部分衔接的约定。 用来…

分类算法系列③:模型选择与调优 (Facebook签到位置预测)

目录 模型选择与调优 1、介绍 模型选择&#xff08;Model Selection&#xff09;&#xff1a; 调优&#xff08;Hyperparameter Tuning&#xff09;&#xff1a; 本章重点 2、交叉验证 介绍 为什么需要交叉验证 数据处理 3、⭐超参数搜索-网格搜索(Grid Search) 介绍…

合宙Air724UG LuatOS-Air LVGL API控件--图表 (Chart)

图表 (Chart) 一幅图胜过一千个字&#xff0c;通过图表展示出的数据内容能让用户更快速有效的了解数据特征。 代码示例 – 创建图表 chart lvgl.chart_create(lvgl.scr_act(), nil) lvgl.obj_set_size(chart, 200, 150) lvgl.obj_align(chart, nil, lvgl.ALIGN_CENTER, 0, …

聊聊Http服务化改造实践

在微服务架构体系中远程RPC调用主要包括Dubbo与Http调用两个大类&#xff0c;由于Dubbo拥有服务注册中心&#xff0c;并且起服务的命名非常规范&#xff0c;使用包名.类名.方法名进行描述。 而http调用通常都是使用httpclient等相关类库&#xff0c;这些在使用上并没有问题&am…

常见问题。

警告&#xff1a;There are 2 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene. 解决&#xff1a;两个摄像机两个audio listeners组件&#xff0c;禁用一个就好了。 错误&#xff1a;Scene ‘xxxxx’ couldn’t be loa…

在 Amazon 搭建无代码可视化的数据分析和建模平台

现代企业常常会有利用数据分析和机器学习帮助解决业务痛点的需求。如制造业中&#xff0c;利用设备采集上来的数据做预测性维护&#xff0c;质量控制&#xff1b;在零售业中&#xff0c;利用客户端端采集的数据做渠道转化率分析&#xff0c;个性化推荐等。 亚马逊云科技开发者…

能直接运营的发接任务平台小程序搭建开发演示

有个项目估计做过互联网的小伙伴都听说过——发接任务平台。 基本每年都有发接任务平台关站&#xff0c;但又有新的平台出来&#xff0c;往复循环&#xff0c;无比热闹。这在互联网圈不常见&#xff0c;互联网项目很多都是风头过去了就结束了&#xff0c;但发接任务年年似乎都…

HTML 播放器效果

效果图 实现代码 <!DOCTYPE HTML> <html><head><title>爱看动漫社区 | 首页 </title><link href"css/bootstrap.css" relstylesheet typetext/css /><!-- jQuery --><script src"js/jquery-1.11.0.min.js"…

进程间通信-Binder

Binder Binder框架概述服务端Binder驱动客户端 设计服务端和客户端设计服务端客户端设计 Binder与ServiceServiceAIDL 保证包裹内参数顺序IMusicPlayerServiceProxyStub 系统服务中的Binder对象ServiceManger管理的服务理解Manger功能快捷键合理的创建标题&#xff0c;有助于目…

19 Linux之Python定制篇-apt软件管理和远程登录

19 Linux之Python定制篇-apt软件管理和远程登录 文章目录 19 Linux之Python定制篇-apt软件管理和远程登录19.1 apt软件管理19.1.1 apt介绍19.1.2 更新软件下载地址-阿里源19.1.3 使用apt完成安装和卸载vim 19.2 远程登录Ubuntu 学习视频来自于B站【小白入门 通俗易懂】2021韩顺…

两个pdf文件合并为一个怎么操作?分享pdf合并操作步骤

不管是初入职场的小白&#xff0c;还是久经职场的高手&#xff0c;都必须深入了解pdf&#xff0c;特别是关于pdf的各种操作&#xff0c;如编辑、合并、压缩等操作&#xff0c;其中合并是这么多操作里面必需懂的技能之一&#xff0c;但是很多人还是不知道两个pdf文件合并为一个怎…

基于材料生成算法优化的BP神经网络(预测应用) - 附代码

基于材料生成算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于材料生成算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.材料生成优化BP神经网络2.1 BP神经网络参数设置2.2 材料生成算法应用 4.测试结果&#xff1a;5…

【Tkinter系列09/15】小部件(Scrollbar

22. 小部件Scrollbar 许多小部件&#xff08;如列表框和画布&#xff09;可以 就像将窗口滑动到更大的虚拟区域一样。你 可以将滚动条小部件连接到它们&#xff0c;为用户提供 相对于内容滑动视图的方式。 下面是带有关联条目小部件的屏幕截图 滚动条小部件&#xff1a; 滚动条…

CSS学习笔记03

CSS笔记03 盒子模型 什么是盒子模型 概念&#xff1a; CSS 盒子模型就是在网页设计中经常用到的一种思维模型&#xff0c;是 CSS 布局的基石&#xff0c;主要规定了元素是如何显示的以及元素间的相互关系。定义所有元素都可以有像盒子一样的平面空间和外形。包含内容区、内边…

汉服网上购物商城穿搭交流的微信小程序的设计与实现

社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。手机具有便利性&#xff0c;速度快&#xff0c;效率高&#xff0c;成本低等优点。 因此&#xff0c;构建符合自己要求的操作系统是非…

Redis项目实战——优惠券秒杀

目录 Redis自增功能解决全局唯一IDRedis实现优惠券秒杀的主要思路实现过程中出现的问题及解决方法超卖问题方案1 悲观锁方案2 乐观锁 一人一单问题分布式锁如何用Redis实现分布式锁&#xff1f; Redis优化秒杀消息队列实现异步秒杀List发布订阅模式Stream Redis自增功能解决全局…