【Spring Boot】认识 JPA 的接口

认识 JPA 的接口

  • 1.JPA 接口 JpaRepository
  • 2.分页排序接口 PagingAndSortingRepository
  • 3.数据操作接口 CrudRepository
  • 4.分页接口 Pageable 和 Page
  • 5.排序类 Sort

JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口,可简化现有的持久化开发工作。可以使 Spring 找到自定义接口,并生成代理类,后续可以把自定义接口注入 Spring 容器中进行管理。在自定义接口过程中,可以不写相关的SQL操作,由代理类自动生成。

在这里插入图片描述
此前,在《分层开发 Web 应用程序》这篇博文中,已经讲述了 Repository 的概念,在此和大家一起回顾一下。

在 Spring 中有 Repository 的概念,Repository 原意指的是 仓库,即 数据仓库 的意思。Repository 居于 业务层数据层 之间,将两者隔离开来,在它的内部封装了数据查询和存储的逻辑。这样设计的好处有两个:

  • 降低层级之间的耦合:更换、升级 ORM 引擎(Hibernate)并不会影响业务逻辑。
  • 提高测试效率:如果在测试时能用 Mock 数据对象代替实际的数据库操作,运行速度会快很多。

DAO 是传统 MVC 中 Model 的关键角色,全称是 Data Access Object。DAO 直接负责数据库的存取工作,乍一看两者非常类似,但从架构设计上讲两者有着本质的区别。

Repository 蕴含着真正的 OO 概念,即一个数据仓库角色,负责所有对象的持久化管理。DAO 则没有摆脱数据的影子,仍然停留在数据操作的层面上。Repository 是相对对象而言,DAO 则是相对数据库而言,虽然可能是同一个东西 ,但侧重点完全不同。

在 Spring 和 Spring Data JPA 中,有三种 Repository 接口方便开发者直接操作数据仓库。它们之间的关系如下:
在这里插入图片描述

1.JPA 接口 JpaRepository

JpaRepository 继承自 PagingAndSortingRepository。该接口提供了 JPA 的相关实用功能, 以及通过 Example 进行查询的功能。Example 对象是 JPA 提供用来构造查询条件的对象。该接口的关键代码如下:

public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {}

在上述代码中,T 表示 实体对象,ID 表示 主键。ID 必须实现序列化。

JpaRepository 提供的方法如下表所示。

方法
描述
List<T> findAll();查找所有实体
List<T> findAll(Sort var1);排序、查找所有实体
List<T> findAllById(Iterable<ID> var1);返回制定一组 ID 的实体
<S extends T> List<S> saveAll(Iterable<S> var1);保存集合
void flush();执行缓存与数据库同步
<S extends T> S saveAndFlush(S var1);强制执行持久化
void deleteInBatch(Iterable<T> var1);删除一个实体集合
void deleteAllInBatch();删除所有实体
T getOne(ID var1);返回 ID 对应的实体。如果不存在,则返回空值
<S extends T> List<S> findAll(Example<S> var1);查询满足 Example 的所有对象
<S extends T> List<S> findAll(Example<S> var1, Sort var2);查询满足 Example 的所有对象,并且进行排序返回

2.分页排序接口 PagingAndSortingRepository

PagingAndSortingRepository 继承自 CrudRepository 提供的分页和排序方法。其关键代码如下:

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { 
	Iterable<T> findAll(Sort var1);
	Page<T> findAll(Pageable var1);
}

其方法有如下两种

  • Iterable<T> findAII(Sort sort):排序功能。它按照 sort 制定的排序返回数据。
  • Page<T> findAll(Pageable pageable):分页查询(含排序功能)。

3.数据操作接口 CrudRepository

CrudRepository 接口继承自 Repository 接口,并新增了增加、删除、修改和查询方法。 CrudRepository 提供的方法见下表:

方法
说明
<S extends T> S save(S entity)保存实体。当实体中包含主键时,JPA 会进行更新操作
<S extends T> Iterable<S> saveAll(Iterable<S> entities)保存所有实体。实体必须不为空
Optional<T> findById(ID id)根据主键 id 检索实体
boolean existsById(ID id)根据主键 id 检索实体,返回是否存在。值为布尔类型
Iterable<T> findAll()返回所有实体
Iterable<T> findAllById(Iterable<ID> ids)根据给定的一组 id 值返回一组实体
long count()返回实体的数量
void deleteById(ID id)根据 id 删除数据
void delete(T entity)删除给定的实体
void deleteAll(Iterable<? extends T> entities)删除实体
void deleteAll()删除所有实体

4.分页接口 Pageable 和 Page

Pageable 接口用于构造翻页查询,返回 Page 对象。Page 从 0 0 0 开始分页。

例如,可以通过以下代码来构建文章的翻页查询参数。

@RequestMapping("/article")
public ModelAndView articleList(@RequestParam(value = "start", defaultvalue = "0") Integer start, 
								@RequestParam(value = "limit", defaultvalue = "10") Integer limit) {
  start = start < 0 ? 0 : start;  
  Sort sort = new Sort(Sort.Direction.DESC, "id");
  Pageable pageable = PageRequest.of(start, limit, sort);
  Page<Article> page = articleRepository.findAll(pageable);
  ModelAndView mav = new ModelAndView("admin/article/list");
  mav.addObject("page", page);
  return mav;
}

然后,再调用它的参数获取总页数、上一页、下一页和末页,见以下代码。

<div>
	<a th:href="@(/article(start=0)}">[首页]</a>
	<a th:if="$(not page.isFirst())" th:href="@{/article(start=${page.number-1})}">[上页]</a>
	<a th:if="$(not page.isLast())" th:href="@(/article(start=$(page.number+1})}">[下页]</a>
	<a th:href="@{/article(start=$(page.totalPages-1}))">[末页]</a>
</div>

5.排序类 Sort

Sort 类专门用来处理排序。最简单的排序就是先传入一个属性列,然后根据属性列的值进行排序。默认情况下是升序排列。它还可以根据提供的多个字段属性值进行排序。

例如以下代码是通过 Sort.Order 对象的 List 集合来创建 Sort 对象的:

List<Sort.Order> orders = new ArrayList<>();
orders.add(new Sort.Order(Sort.Direction.DESC, "id"));
orders.add(new Sort.Order(Sort.Direction.ASC, "view"))Pageable pageable = PageRequest.of(start, limit, sort);
Pageable pageable = PageRequest.of(start, limit, Sort.by(orders));

Sort 排序的方法还有下面几种:

  • 直接创建 Sort 对象,适合对单一属性做排序。
  • 通过 Sort.Order 对象创建 Sort 对象,适合对单一属性做排序。
  • 通过属性的 List 集合创建 Sort 对象,适合对多个属性采取同一种排序方式的排序。
  • 通过 Sort.Order 对象的 List 集合创建 Sort 对象,适合所有情况,比较容易设置排序方式。
  • 忽略大小写排序。
  • 使用 JpaSort.unsafe 进行排序。
  • 使用聚合函数进行排序。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汽车尾灯(转向灯)电路设计

即当汽车进行转弯时,司机打开转向灯,尾灯会根据转向依次被点亮,经过一定的间隔后,再全部被消灭。不停地重复,直到司机关闭转向灯。 该效果可由以下电路实现: 完整电路图: 02—电路设计要点 延时电路的要点主要有两个: 一、当转向开关被按下时,LED需要逐个亮起; 二、LED被逐…

【AI编译器】triton学习:编程模型

介绍 动机 在过去十年里&#xff0c;深度神经网络 (DNNs) 已成为机器学习 (ML) 模型的一个重要分支&#xff0c;能够实现跨领域多种应用中的最佳性能。这些模型由一系列包括参数化&#xff08;如滤波器&#xff09;和非参数化&#xff08;如缩小值函数&#xff09;元件组成的…

STM32 HAL库里 串口中断回调函数是在怎么被调用的?

跟着正点原子学习的HAL库写串口接收程序的时候一直有困惑&#xff0c;使用HAL_UART_Receive_IT开启接收中断后&#xff0c;为啥处理函数要写在HAL_UART_RxCpltCallback里&#xff0c;中断发生的时候是怎么到这个回调函数里去的&#xff1f; void MX_USART1_UART_Init(void) {h…

x-api-eid-token参数分析与加密算法还原

文章目录 1. 写在前面2. 接口分析3. 算法实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

操作符详解(下) (C语言)

操作符详解下 操作符的属性1.优先级2.结合级 表达式求值1.整型提升2.如何进行整形提升呢&#xff1f;3.算术转换4.问题表达式解析 操作符的属性 C语言的操作符有2个重要的属性&#xff1a;优先级、结合性&#xff0c;这两个属性决定了表达式求值的计算顺序。 1.优先级 优先级…

【操作系统期末速成】 EP04 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点七&#xff1a;进程通信2.2 考点八&#xff1a;线程的概念2.3 考点九&#xff1a;处理机调度的概念及原则2.4 考点十&#xff1a;调度方式与调度算法 一、前言&#x1f680;…

DM 的断点续传测试

作者&#xff1a; 大鱼海棠 原文来源&#xff1a; https://tidb.net/blog/4540ae34 一、概述 DM有all、full、incremental三种数据迁移同步方式&#xff08;task-mode&#xff09;&#xff0c;在all同步模式下&#xff0c;因一些特殊情况&#xff0c;需要变更上游MySQL的数…

【解释】i.MX6ULL_IO_电气属性说明

【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞&#xff08;Hysteresis&#xff09;是什么&#xff1f;1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 03

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econom…

Analyze an ORA-12801分析并行 parallel 12801 实际原因

"ORA-06512: at "PKG_P_DATA", line 19639 ORA-06512: at "PKG_P_DATA", line 19595 ORA-06512: at "PKG_P_DATA", line 14471-JOB 调用 -ORA-12801: error signaled in parallel query server P009, instance rac2:dwh2 (2) Error: ORA-12…

Python实现无头浏览器采集应用的反爬虫与反检测功能解析与应对策略

Python实现无头浏览器采集应用的反爬虫与反检测功能解析与应对策略 随着网络数据的快速增长&#xff0c;爬虫技术在数据采集、信息分析和业务发展中扮演着重要的角色。然而&#xff0c;随之而来的反爬虫技术也在不断升级&#xff0c;给爬虫应用的开发和维护带来了挑战。为了应…

Linux多进程和多线程(三)进程间通讯-信号处理方式和自定义处理函数

进程间通信之信号 信号信号的种类 信号在操作系统中的定义如下: 信号的处理流程在 Linux 中对信号的处理⽅式 自定义信号处理函数 信号的发送 kill() 函数:raise() 函数: 示例 : 创建⼀个⼦进程&#xff0c;⼦进程通过信号暂停&#xff0c;⽗进程发送 终⽌信号等待信号 pause()…

【嵌入式Linux】<总览> 多线程(更新中)

文章目录 前言 一、多线程 1. 概述 2. 创建线程 3. 线程退出 4. 线程回收 5. 线程分离 6. 线程取消 7. 线程的ID比较 二、线程同步 前言 记录学习多线程的知识重点与难点&#xff0c;若涉及版权问题请联系本人删除&#xff01; 一、多线程 1. 概述 线程是轻量级的…

期末考试后班主任如何发布学生成绩?

期末考试成绩一出&#xff0c;家长们便急切地想要了解孩子的学习情况。以往&#xff0c;老师们需要一个个私信家长&#xff0c;将成绩单发送出去&#xff0c;这项工作既繁琐又耗时。期末之际&#xff0c;老师们的工作本就繁重&#xff0c;如何有效减轻他们的负担&#xff0c;让…

构建现代医疗:互联网医院系统源码与电子处方小程序开发教学

本篇文章&#xff0c;笔者将探讨互联网医院系统的源码结构和电子处方小程序的开发&#xff0c;帮助读者更好地理解和掌握这些前沿技术。 一、互联网医院系统源码结构 互联网医院系统通常由多个模块组成&#xff0c;每个模块负责不同的功能。以下是一个典型的互联网医院系统的主…

【云原生】Prometheus 使用详解

目录 一、前言 二、服务监控概述 2.1 什么是微服务监控 2.2 微服务监控指标 2.3 微服务监控工具 三、Prometheus概述 3.1 Prometheus是什么 3.2 Prometheus 特点 3.3 Prometheus 架构图 3.3.1 Prometheus核心组件 3.3.2 Prometheus 工作流程 3.4 Prometheus 应用场景…

Linux 进程信号篇

文章目录 1. 生活中的信号2. 信号的概念3. 信号的产生3.1 系统调用3.2 软件条件3.2 异常3.3 Core和Term的区别 4. 信号的保存5. 信号的处理5.1 地址空间的进一步理解5.2 键盘输入数据的过程5.3 理解OS如何正常运行5.3.1 OS如何运行5.3.2 如何理解系统调用 5.4 内核态和用户态 6…

容器技术-docker4

一、docker资源限制 在使用 docker 运行容器时&#xff0c;一台主机上可能会运行几百个容器&#xff0c;这些容器虽然互相隔离&#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&#xff0c;那么容器之间会互相影响&#xff0c;小的来说…

容器技术-docker2

容器化技术Docker Docker介绍 官网&#xff1a; docker.io docker.com 公司名称&#xff1a;原名dotCloud 14年改名为docker 容器产品&#xff1a;docker 16年已经被更名为Moby docker-hub docker.io docker容器历史 和虚拟机一样&#xff0c;容器技术也是一种资源隔…

为什么前端传了token,后端一直获取不到?一直报跨域错误?

这是我的前端代码 这是我的后端拦截器 那就需要了解一下 预检请求 对于非简单请求&#xff08;如PUT、DELETE或包含自定义HTTP头的请求&#xff09;&#xff0c;浏览器会先发送一个OPTIONS请求到目标服务器&#xff0c;询问是否允许该跨域请求。这个过程称为预检请求。 当opt…