Hibernate(Spring Data)抓取策略

这篇具有很好参考价值的文章主要介绍了Hibernate(Spring Data)抓取策略。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

示例代码放到最后,使用的是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属性集合有二十个对象
Hibernate(Spring Data)抓取策略,hibernate,java,后端

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方法时才会去获取数据
Hibernate(Spring Data)抓取策略,hibernate,java,后端

Hibernate(Spring Data)抓取策略,hibernate,java,后端

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提供了多种抓取策略用于加载关联实体对象,包括即时加载、延迟加载、手动加载、子查询加载和基于批处理的加载。选择合适的抓取策略可以提高查询性能和减少数据库交互次数,但需要根据实际情况和性能要求进行综合考虑。文章来源地址https://www.toymoban.com/news/detail-686806.html

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>

到了这里,关于Hibernate(Spring Data)抓取策略的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高校毕业生就业信息管理系统的设计与实现(Spring + Spring MVC +Hibernate)

    目 录 摘要 I ABSTRACT II 1 引言 1 1.1 高校毕业生就业信息管理系统现状 1 1.2毕业生就业信息管理系统设计目标 1 1.3 可行性研究 2 1.3.1 研究目的 2 1.3.2 经济可行性 2 1.3.3 技术可行性 2 1.3.4法律条文可行性 3 1.3.5可行性研究结论 3 2 系统开发技术介绍 4 2.1 Java EE 、JSP概述 4 2.2系统开发

    2024年02月05日
    浏览(48)
  • Spring Boot使用 Hibernate-Validator校验参数时的长度校验

    今天在使用Validator框架数据验证的时候碰到了三个类似的注解,都是用来限制长度,但是用法上有区别:  @Size是一个Bean验证注释,用于验证关联的String具有的长度受最小值和最大值限制的值.  @Length是一个Hibernate特定的注释,与@Size具有相同的含义; 两者的区别: ​ 用@length限

    2024年02月14日
    浏览(41)
  • java之路——带你了解Hibernate与基本过程

    Hibernate框架的发展可以追溯到2001年,它在过去的几年里获得了广泛的应用和持续的发展。 其中的发展演变: 初期版本(2001-2006年): Hibernate框架最早由Gavin King创建,目的是为了简化Java应用程序与关系数据库之间的数据交互。在这个阶段,Hibernate开始以一种简单但强大的方

    2024年02月12日
    浏览(44)
  • Hibernate框架【一】——HIbernate框架介绍

    Hibernate框架【三】——基本映射——一对一映射 Hibernate框架【四】——基本映射——多对一和一对多映射 Hibernate框架【五】——基本映射——多对多映射 Hibernate是一个开源的Java对象关系映射(ORM)框架,它提供了一种方便的方式将Java对象与关系型数据库进行映射和交互。

    2024年02月09日
    浏览(70)
  • 【IDEA使用指南】使用Hibernate框架的Java项目,如何通过数据库表自动生成实体模型?

    步骤1:找到并打开“Persistence”工具栏。 如下图所示,找到 “View - Tool Windows - Persistence”,点击“Persistence”。 步骤2:找到并打开“Import Database Schema” 窗口。 在开发工具左下角会弹出持久化配置的工具栏“Persistence”,如下图所示。单击之后有一个弹框,找到弹框中的项

    2024年02月05日
    浏览(65)
  • Hibernate 配置文件(hibernate.cfg.xml、hbm.xml)

      目录 Hibernate.xml  1、数据库的基本信息。 2、集成 C3P0,设置数据库连接池信息。 3、Hibernate 基本信息。  4、注册实体关系映射文件。  实体关系映射文件 (实体类文件名.hbm.xml) 1、hibernate-mapping标签的属性 2、class标签的属性  2.1、dynamic-insert:动态添加 (默认为false)

    2023年04月08日
    浏览(41)
  • Hibernate(一)——入门

    在之前经常用到操作数据库的框架是Mybatis或者Mybatis-plus。 Hibernate在項目中用过,但没有深入的了解过,所以这次趁着假期把这个框架了解一下。 Hibernate就是一个 持久层 的 ORM 框架 什么是ORM框架? 利用描述对象和数据库表之间映射的元数据,自动把Java应用程序中的对象,持

    2024年02月02日
    浏览(47)
  • hibernate入门

    Hibernate 是一个开源的 ORM(对象关系映射)框架,它可以将 Java 对象与数据库表进行映射,从而实现面向对象的数据持久化。使用 Hibernate,可以避免手动编写 SQL 语句,从而提高开发效率,并且可以轻松地切换不同的数据库。 entity 实体类是映射到数据库表中的 Java 类,它包含

    2024年02月13日
    浏览(46)
  • hibernate 懒加载

    @Entity @Table(name = \\\"Student\\\") public class StudentInformation { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int rollno; private String name; // Mapping to the other table @OneToMany(mappedBy =\\\"stud\\\" ,cascade = CascadeType.ALL,fetch= FetchType.LAZY ) private SetAddress addressSet=new HashSet();; public StudentInformation() { } public St

    2024年02月09日
    浏览(90)
  • 9.3. Hibernate框架

    Hibernate是一个开源的持久层框架,它可以帮助我们将Java对象映射到数据库表中,并实现对象的持久化操作。Hibernate提供了丰富的API,可以方便地进行CRUD(增删改查)操作,而无需手动编写复杂的JDBC代码。 9.3.1. Hibernate核心组件 Hibernate主要包含以下几个核心组件: SessionFact

    2024年02月08日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包