解析资源库架构模式

无论应用程序的设计方法和实现技术如何发展,数据访问仍然是任何系统都需要考虑的基础技术问题。针对数据访问过程,我们可以理解为任何一个系统都应该存在这样一个起点,我们可以从这个起点遍历到具体的数据。换句话说,系统中应该存在一个数据提供者,通过这个数据提供者就能获取到所有想要的数据对象。而我们今天要介绍的资源库本质上就是这样一种数据的提供者。


关于如何更好的设计上图中的资源库,业界也诞生了一些主流的设计方法。这些设计方法解决的核心问题有两个,即:

  1. 如何实现应用程序的内存数据和具体持久化数据之间的转换关系?
  2. 如何在应用程序中抽离独立的数据持久化访问入口?

第一个问题的解决思路比较简单,一般做法是实现一个数据映射层。第二个问题是第一个问题的延伸,我们通过资源库来提供统一的数据访问入口。下图展示了资源库的基本结构,从中可以看出内存数据与持久化数据的映射关系,以及资源库与持久化媒介之间的交互过程。


在架构设计上,资源库是一种常见的架构模式,应用非常广泛,我们经常使用的Hibernate、Mybatis等各种ORM框架实际上都是这一架构模式的具体实现框架。今天,我们就将围绕资源库架构模式的基本概念以及具体应用场景展开详细讨论。

资源库架构模式 

简单来说,资源库作为对象的提供者,指的就是能够实现对象的持久化。持久化的媒介有很多,传统的关系型数据库、各种NoSQL以及代表持久化新方向的NewSQL都可以进行数据的CRUD操作。显然,针对这些不同持久化媒介的具体技术体系是不一样的。


为了通过资源库来屏蔽数据访问的技术差异性和复杂性,我们需要设计资源库的具体表现形式。下图展示了其中的一种表现形式。


在上图中,客户端通过一定的查询条件来对资源库发起请求,然后资源库把数据访问的具体技术和实现策略封装起来。这样,开发人员通过资源库就可以实现各种类型的数据访问操作。

在这些数据访问操作中,主要的应用场景是数据查询。因此,对查询类操作的支持程度也是衡量一个资源库实现方案的重要标准。通常,开发人员可以通过构建不同的规约化查询对象来对资源库发起请求。下图展示这一应用场景下的类图结构。


在上图中,基于Account这个业务对象,我们把这两个规约化查询对象命名为AccountSpecificationByUserName和AccountSpecificationByAgeRange。而这里的Repository和Specification接口分别代表资源库和查询对象。

看了这张图,你可以会觉得困惑,我们如何实现图中的各个技术组件的?不用担心,业界已经诞生了一些资源库架构模式的实现框架,其中最具代表性的就是Spring家族的Spring Data框架。让我们一起来看一下。

Spring Data中的资源库模式

Spring Data是Spring家族中专门用于实现数据访问的开源框架,其核心理念是支持对所有持久化媒介进行资源化配置从而实现数据访问。我们知道,数据访问需要完成业务对象与持久化数据之间的映射并对外提供访问入口,Spring Data基于资源库架构模式抽象出一套实现该模式的统一数据访问方式。

Spring Data和资源库

我们先来看Spring Data中用来表示资源库的Repository接口。Repository接口是Spring Data中对数据访问的最高层抽象,接口定义如下所示。

public interface Repository<T, ID> {

}

我们看到Repository接口只是一个空接口,通过泛型指定了业务实体对象的类型和ID。在Spring Data中,存在一大批Repository接口的子接口和实现类,该接口的部分类层结构如下所示。


可以看到CrudRepository 接口是对Repository接口的最常见扩展,添加了业务对象的CRUD操作功能,定义如下。

public interface CrudRepository<T, ID> extends Repository<T, ID> {

  //保存单个实体对象

<S extends T> S save(S entity);

//保存一组实体对象

<S extends T> Iterable<S> saveAll(Iterable<S> entities);

//根据Id查询单个实体对象

Optional<T> findById(ID id);

//判断指定Id的对象是否存在

boolean existsById(ID id);

//获取所有实体对象

Iterable<T> findAll();

  //根据一组Id获取对应的一组实体对象

Iterable<T> findAllById(Iterable<ID> ids);

//获取对象总数

long count();

//根据Id删除实体对象

void deleteById(ID id);

//根据实体对象执行删除操作

void delete(T entity);

  //删除一组实体对象

void deleteAll(Iterable<? extends T> entities);

//删除所有实体对象

void deleteAll();

}

这些方法都是自解释的,我们可以看到CrudRepository接口提供了一组非常实用的数据访问操作。

在Spring Data的官方网站中列出来其所提供的所有组件,包括针对关系型数据库的JPA 资源库,也包括针对MongoDB、Neo4j、Redis等各种NoSQL对应的资源库等。


在接下来的内容中,我们重点讨论的是用于实现关系型数据库访问的Spring Data JPA,在该组件中存在一个JpaRepository接口,该接口是CrudRepository的子接口。在日常开发过程中,我们通常可以借助于方法名衍生查询功能来使用JpaRepository接口。

所谓的方法名衍生查询是Spring Data的查询特色之一,通过在方法命名上直接使用查询字段和参数,资源库就能自动识别相应的查询条件并组装对应的查询语句。典型的示例如下所示。

public interface AccountRepository extends JpaRepository<Account,

Long> {

List<Account> findByFirstNameAndLastName(String firstName, String

lastName);

}

在上面的例子中,通过findByFirstNameAndLastname这样符合普通语义的方法名,并在参数列表中按照方法名中参数的顺序和名称传入相应的参数,即第一个参数是fistName,第二个参数lastName,Spring Data就能自动组装SQL语句从而实现衍生查询。是不是很神奇?

Specification机制

介绍完JpaRepository的基本用法之后,我们再来介绍和资源库架构模式密切相关的一种规约化查询机制,即Specification机制。考虑这样一种场景,我们需要动态的根据不同条件来对某一个对象执行查询操作,那么就可以引入Spring Data JPA中的JpaSpecificationExecutor接口来实现这一目标。

你可能会问,为什么我们需要使用Specification机制呢?核心原因是该机制具备的类型安全性。我们同样来看一个示例,假设我们有一个继承了JpaSpecificationExecutor的OrderJpaRepository,定义如下。

public interface OrderJpaRepository extends JpaRepository<Order, Long>, JpaSpecificationExecutor<Order>{

对于JpaSpecificationExecutor接口而言,背后使用的就是Specification接口,该接口的核心方法就一个,如下所示。

Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder);

通过这里的toPredicate方法,我们就可以根据root中所传入的业务对象,以及CriteriaQuery和CriteriaBuilder中的查询条件来实现动态化查询。

基于Specification机制,我们也来给出一个典型的实现方法,如下所示。

public Order getOrderByOrderNumberBySpecification(String orderNumber) {

Order order = new Order();

order.setOrderNumber(orderNumber);

Specification<Order> spec = new Specification<Order>() {

            @Override

            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

                Path<Object> orderNumberPath = root.get("orderNumber");

              

                Predicate predicate = cb.equal(orderNumberPath, orderNumber);

                return predicate;

            }

        };

return orderJpaRepository.findOne(spec).orElse(new Order());

}

可以看到,在这里的toPredicate方法中,我们从root对象中获取了“orderNumber”属性,然后通过cb.equal方法将该属性与传入的“orderNumber”参数进行比对,从而完成查询条件的构建。这种实现方式是资源库使用过程中的常见做法。

数据访问是一切应用系统的基础,而资源库架构模式为我们实现数据访问提供了设计思想和方法。架构模式的落地需要具体的开发框架。基于资源库架构模式,Spring Data为开发人员提供了一系列用于完成CRUD操作的工具方法,尤其是针对最常用的查询操作更是专门进行了提炼和设计使得开发过程变得简单而高效。在今天的内容中,我们基于资源库架构模式以及Spring Data框架给出了数据访问过程中的一些代码示例,这些代码示例都可以直接应用到日常开发过程中。

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

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

相关文章

Python爬虫掌握-----4实战(爬取视频)

我们使用爬虫时难免会遇到爬取视频的情况&#xff0c;其实爬取图片视频&#xff0c;内容都是一样的。这里以b站视频为例。 一、开始 1.找到url&#xff0c;请求url 防盗链&#xff0c;需要写在UA伪装中 正常的三步&#xff1a; 1.url 2.requests请求 3.UA伪装 import req…

2024最新网络安全自学路线,内容涵盖3-5年技能提升

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

做一个能和你互动玩耍的智能机器人之二

智能机器人硬件的一些注意事项和知识和初学者的误区。 一。不要担心不会焊接&#xff0c;我也是购买后才发现&#xff0c;现在的很多板子和元器件可以无焊接使用&#xff0c;比如借助杜邦线和面包板&#xff0c;可以很方便连接。 二。arduino有很多种&#xff0c;一般用的是n…

【Java算法专场】二分查找(上)

目录 前言 什么是二分查找&#xff1f; 二段性 ​​​​​​​​​​​​​​​​​​​​​二分查找 算法分析 算法步骤 算法代码 算法示例 模板 在排序数组中查找元素的第一个和最后一个位置 算法分析 算法步骤 算法代码 算法示例 搜索插入位置 算法分析 算法步…

IEC104转MQTT网关支持将IEC104数据转换为华为云平台可识别的格式

随着智能电网和物联网技术的深度融合&#xff0c;传统电力系统中的IEC104协议设备正逐步向更加开放、智能的物联网体系转型。华为云作为全球领先的云计算和AI服务提供商&#xff0c;其物联网平台为IEC104设备的接入与数据处理提供了强大的支撑。本文将探讨IEC104转MQTT网关在MQ…

KETTLE运行出现乱码和无法执行问题及解决方案

一、乱码问题 &#xff08;1&#xff09;出现乱码&#xff0c;在数据库连接里面的选项里面加入&#xff1a;characterEncodingutf8和tinyInt1isBitfalse &#xff08;2&#xff09;取消简易转换&#xff0c;点开表输入&#xff0c;取消”允许简易转换”选项&a…

vue3.0学习笔记(一)——vue3简介与vite脚手架的使用

1. 为什么学vue3 Vue3现状&#xff1a; vue-next 2020年09月18日&#xff0c;正式发布vue3.0版本。但是由于刚发布周边生态不支持&#xff0c;大多数开发者处于观望。现在主流组件库都已经发布了支持vue3.0的版本&#xff0c;其他生态也在不断地完善中&#xff0c;这是趋势。…

梯度下降算法在逻辑回归中的应用

逻辑回归简介 sigmoid函数&#xff1a; g ( z ) 1 1 e − z g(z) \frac{1}{1e^{-z}} g(z)1e−z1​ 逻辑回归假设函数&#xff1a; y ^ h θ ( x ) g ( θ T x ) 1 1 e − θ T x \hat{y} h_{\theta}(x) g(\theta^Tx) \frac{1}{1e^{-\theta^Tx}} y^​hθ​(x)g(θTx)…

我的世界!

每位冒险家在《我的世界》中的出生点都各不相同&#xff0c; 有的出生在桦木森林&#xff0c;有的出生在草原&#xff0c; 还有的出生在临近海洋的沙滩。 这些环境叫做生物群系&#xff0c;也常被称为生态系统。 在《我的世界》中的不同生物群系具有不同的地域特色—— 不…

Redis的五种数据类型与命令

目录 引言 一 Redis的特性 二 Redis的安装 三 Redis的优点 四 Redis的五种数据类型与命令 五 Redis的配置文件 引言 Redis是什么&#xff1f; Remote Dictionary Service(远程字典服务器) Redis 是一个开源的(BSD许可)的&#xff0c;C语言编写的&#xff0c;高性能的数…

羊大师:夏夜贪凉,但为啥肚子还要‘保暖计划’?

在这个夏夜&#xff0c;当空调与风扇齐飞&#xff0c;冰镇西瓜与凉面共舞之时&#xff0c;你是否也曾有过这样的疑惑&#xff1a;明明热得汗流浃背&#xff0c;为啥老一辈总念叨着“睡觉再热也要给肚子盖被子”&#xff1f;这背后&#xff0c;藏着的可不仅仅是老一辈的固执&…

centos7手动编译安装redis-6.2.1.tar.gz

本章教程,主要通过手动编译安装的方式,进行安装redis-6.2.1版本,如果需要安装其它版本的,可以在这里找到对应版本进行下载,安装步骤基本上差不多。 下载地址:https://download.redis.io/releases/ 一、下载安装包 wget https://download.redis.io/releases/redis-6.2.1.…

SSM学习9:SpringBoot简介、创建项目、配置文件、多环节配置

简介 SpringBoot式用来简化Spring应用的初始搭建以及开发过程的一个框架 项目搭建 File -> New -> Project 选中pom.xml文件&#xff0c;设置为maven项目 项目启动成功 可以访问BasicController中的路径 配置文件 在resources目录下 application.properties 默…

powershell自定义命令别名

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、查看命令别名二、常见的别名三、自定义别名1.GUI编辑2.命令行编辑 总结 前言 有时候在windows上使用powershell时候常常苦于别名问题&#xff0c;像我这样…

昇思25天学习打卡营第25天|基于MindSpore的GPT2文本摘要

基于MindSpore的GPT2文本摘要 Tips&#xff1a;安装依赖库 pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore2.2.14 pip install mindnlp下载数据集&#xff1a; from mindnlp.utils import http_get# download dataset url https://download.mindspore.…

Android AutoSize屏幕适配:适配不同屏幕大小的尺寸,让我们无需去建立多个尺寸资源文件

目录 AutoSize是什么 AutoSize如何使用 一、AndroidautoSize是什么 在开发产品的时候&#xff0c;我们会遇到各种各样尺寸的屏幕&#xff0c;如果只使用一种尺寸去定义控件、文字的大小&#xff0c;那么到时候改起来就头皮发麻。以前使用dime的各种类库&#xff0c;文件太多…

敏捷CSM证书国家认可嘛?有什么价值?

CSM证书&#xff0c;全称为Certified Scrum Master&#xff0c;是由Scrum Alliance&#xff08;敏捷联盟&#xff09;颁发的一项国际公认的敏捷管理领域认证。该证书不仅在全球范围内受到广泛认可&#xff0c;也在国内得到了业界的广泛关注和重视。 CSM证书的背景 CSM证书是基…

从原理到实践:开发视频美颜SDK与主播美颜工具详解

本篇文章&#xff0c;笔者将深入探讨视频美颜SDK的开发原理和实践应用&#xff0c;重点介绍如何打造一款功能强大的主播美颜工具。 一、视频美颜的基本原理 视频美颜的核心在于图像处理技术&#xff0c;主要包括面部识别、图像增强和特效处理。 1.面部识别 常见的面部识别算…

Codeforces Round 874 (Div. 3)(A~D题)

A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是&#xff1a;前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…

昇思25天学习打卡营第20天|CV-ResNet50图像分类

打卡 目录 打卡 图像分类 ResNet网络介绍 数据集准备与加载 可视化部分数据集 残差网络构建 Building Block 结构 代码实现 Bottleneck结构 代码实现 构建ResNet50网络 代码定义 模型训练与评估 可视化模型预测 重点&#xff1a;通过网络层数加深&#xff0c;感知…