Spring Data学习笔记Day01-SpringData入门

Spring Data基本介绍

目录

  • Spring Data Redis 官方API参考手册!
  • ★ Spring Data的价值
  • ★ Spring Data及其子项目
  • ★ 强大的Spring Data
  • ★ Repository接口
  • ★ 具体Repository接口
  • ★ Spring Data JPA开发
  • ★ Spring Boot如何选择DataSource
  • ★ 数据源相关配置
  • ★ 配置第三方数据源(C3P0)
  • ★ 配置多个数据源
  • ★ 方法名关键字查询(全自动)
  • ★ @Query查询(半自动:提供SQL或JPQL)
  • ★ 命名查询
  • ★ 自定义查询(全手动)
  • ★ 样本查询
  • ★ Specification查询

Spring Data Redis 官方API参考手册!

👉:🔗Spring Data Redis 官方API参考手册
👉:🔗Lettuce 6.2.5.RELEASE API官方API参考手册
在这里插入图片描述

★ Spring Data的价值

高度统一:只需要一套API: Spring Data,可以同时访问SQL数据和NoSQL数据库。

真正掌握Spring Data之后,你可以做到随心所欲地访问任意的SQL数据库和NoSQL数据库。


开发者:只需要面向通用的Spring Data API编程,程序就可以自由地在各种SQL或NoSQL技术之间切换。

★ Spring Data及其子项目

从结构上来说,Spring Data相当于是一个总的项目,Spring Data包括如下子项目:
Spring Data JDBC:Spring Data对传统JDBC的封装。
Spring Data JPA:Spring Data对JPA的封装。
Spring Data MongoDB:Spring Data对MongoDB的封装。
Spring Data Redis:Spring Data对Redis的封装。

…

从逻辑关系上来说,Spring Data相当于Spring Data Xxx子项目的抽象层,而Spring Data Xxx是具体实现。
实际上Spring Data还包括一个Spring Data Commons子项目,该子项目就是Spring Data的通用抽象层。


习惯:常常所说的,面向Spring Data编程,其实是面向Spring Data Commons子项目编程,
该子项目才是Spring Data的通用抽象层。

★ 强大的Spring Data

▲ 从代码简化的角度来说,DAO组件(官方叫Repository组件)的各种通常CRUD方法完全不需要开发者编写任何代码,
   Spring Data能通过动态代理的方式动态地生成CRUD方法。
   
   如果你要简单,Spring Data说:OK,你不需要写任何代码。我就能帮你搞定通用的CRUD操作。

▲ 从功能强大的角度来说,Spring Data既允许开发者自定义SQL或NoSQL查询语句来执行查询、从而优化查询。
   
   如果你要优化SQL语句,Spring Data说:OK,你只要用注解提供SQL语句,剩下的查询过程我就能帮你搞定。

▲ 也允许开发者直接调用相应技术的底层API来实现数据访问,完全是鱼和熊掌可以得兼。

   如果你要完全接管数据库访问访问的代码实现,Spring Data说:OK,剩下的交给你了。

★ Repository接口

▲ Repository接口是Spring Data通用抽象层的核心API,所有DAO组件都应该继承它或它的子接口。

Repository接口派生了如下两个子接口:
- CrudRepository:主要提供了各种CRUD方法,继承该接口的DAO组件不用编写任何代码
                   就可执行各种通用的CRUD数据访问及各种数据查询 。
- ReactiveCrudRepository:类似于CrudRepository接口,只不过它的方法都是反应式的,
                   因此它的方法的返回值都是Mono或Flux。

PagingAndSortingRepository接口继承了CrudRepository接口,增加了分页和排序功能。(额外增加了分页和排序的方法)

——补充一点,其实CrudRepository本身也可做分页和排序(通过传入额外参数),因此实际上CrudRepository用得更多一些。

ReactiveSortingRepository接口则继承了ReactiveCrudRepository接口,它相当于PagingAndSortingRepository的反应式版本。

★ 具体Repository接口

前面4个XxxRepository属于Spring Data Commons子项目,属于Spring Data的通用抽象层,如果让DAO组件继承它们,这样DAO组件的底层就可以在任意持久化技术、甚至任意数据存储技术(不管是SQL数据库也好,还是NoSQL数据库也好)之间自由切换。

此外,各Spring Data Xxx子项目也提供了对应的XxxRepository,比如:
Spring Data JPA提供了JpaRepository、
Spring Data MongoDB提供了MongoRepository……

这些针对特定技术的Spring Data Xxx子项目提供的XxxRepository都是PagingAndSortingRepository
或ReactiveSortingRepository的子接口。


一般,并不建议面向XxxRepository接口编程,因为这种接口是属于Spring Data Xxx子项目。不是Spring Data抽象层。

★ Spring Data JPA开发

(1)配置数据源。
(2)配置JPA相关属性,这些属性由JpaProperties类负责处理。
——上面2步都在application.properties中配置即可。
(3)使用JPA注解定义实体类。
(4)继承CrudRepository或其子接口实现DAO组件,如要实现反应式DAO组件,继承ReactiveCrudRepository或其子接口。
我们只需要开发DAO组件的接口,并不需要提供实现类。

   如果要做分页查询,需要使用Pageable参数,但Pageable有个实现类:PageRequest,调用它的of方法即可创建 Pageable对象     

★ Spring Boot如何选择DataSource

HikariCP > Tomcat pooling DataSource > Commons DBCP2

Spring Boot的spring-data-starter-jdbc默认就自带了HikariCP 的JAR包。

如果你不指定任何额外信息,Spring Boot默认会为我们创建HikariCP 的数据源。

★ 数据源相关配置

数据源的通用配置以spring.datasource.*开头的属性进行配置。

spring.datasource.*开头的属性由DataSourceProperties类负责加载、处理。

如果想对特定数据源实现增加配置,可通过特定前缀的属性进行配置,例如:
- spring.datasource.hikari.*:专门配置HikariCP的属性。
- spring.datasource.tomcat.*:专门配置Tomcat池化数据源的属性。
- spring.datasource.dbcp2.*:专门配置DBCP2数据源的属性。


@ConfigurationProperties可修饰类,将该类变成属性处理类。

@ConfigurationProperties还可修饰@Bean配置Bean组件,
此时该注解读取的配置文件中的每个属性都会调用该Bean的一个setter方法
比如在配置文件中读到一个abc属性,它就会尝试调用配置Bean的setAbc()方法

★ 配置第三方数据源(C3P0)

首先需要排除HikariCP依赖库,还要添加C3P0的依赖

▲ 简单配置方式,只要一行(不能定制,早期版本才支持,Spring Boot 2.4开始不再支持):
spring.datasource.type=com.mchange.v2.c3p0.ComboPooledDataSource


▲ 复杂配置(用自定义的数据源代替自动配置的数据源)

(1)先在容器中用@Bean配置一个C3P0数据源
(2)然后用@ConfigurationProperties读取配置属性来对C3P0数据源进行配置

★ 配置多个数据源

可在容器中用@Bean配置多个数据源。

如果希望Spring Boot能依赖注入某个数据源,可用@Primary注解修饰它。

——该注解修饰的数据源将作为整个应用默认的数据源。


【注意:】,如果你要配置多个数据源泉,必须自己显式地在容器中配置多个。

            不可能说你配置一个,Spring Boot帮你自动配置一个,这是不可能的。

            Spring Boot自动配置的DataSource Bean有一个@ConditionalOnMissingBean(DataSource.class)。

★ 方法名关键字查询(全自动)

(1)继承CrudRepository接口的DAO组件可按特定规则来定义查询方法,
     只要这些查询方法的方法名遵守特定的规则,Spring Data将会自动为这些方法生成查询语句、提供方法实现体。

(2)方法名关键字的查询方法能以find...By、read...By、query…By、count…By(查询记录的条数)、get…By开头,
     并在方法名中嵌入特定关键字即可,Spring Data就会自动生成相应的查询方法体。


 ▲ 关键字规则

 在方法名中将属性名、运算符都设计成关键字,比如如下:
 - findByName(String name),这表明根据name属性执行查询。
 - findByAgeGreaterThan(int age):表明查询age属性大于指定值的记录。

 具体可参考教材中表5.1

 ▲ 关键字方法中同样可定义Pagable、Sort参数,用于控制分页和排序。

 说明:如果要做分页或排序的查询,其实没必须要去继承PagingAndSortingRepository,继承CrudRepository也是可行的

 ▲ 需要说明的情况:

 一种情况需要说明,对比如下两个方法:
 - findByAddressAndZip:该方法要根据address和zip两个属性进行查询,
   它对应的JPQL片段为:... where x.address = ?1 and zip = ?2。

 - findByAddressZip:留意该方法名的Address和Zip之间既没有And,也没有Or,
   那就表明用的是“属性路径”方式,表明该方法要根据address属性的zip属性进行查询,
   它对应的JPQL片段为:... where x.address.zip = ?1。


如果你的方法名中的关键字写错了,往往就会报QueryCreateException。

★ @Query查询(半自动:提供SQL或JPQL)

——让开发者指定JPQL或SQL查询,剩下的事情由Spring Data来负责完成:帮你生成查询方法、实现查询功能。


▲ @Query注解

通过使用@Query注解修饰查询方法,可以让查询方法使用自定义的JPQL或SQL执行查询,该注解可以指定如下常用属性:

- name:指定使用哪个命名查询。
        命名查询的本质就是为JPQL或SQL语句起个名字,因此指定使用哪个命名查询也就是指定了JPQL或SQL语句。

- nativeQuery:指定是否为SQL查询,如果该属性为true,表明是原生SQL查询,否则就是JPQL查询。

- value:指定自定义的JPQL或SQL语句。


你想指定JPQL语句也行,你想指定SQL语句也行——你想怎么优化就怎么优化。

▲ Modifying注解

如果@Query注解指定的查询语句要对底层数据进行修改,还需要使用@Modifying注解修饰该方法,

该注解修饰的方法可以修改底层的数据。


【提示:】 Spring Boot有一个很优秀的设计,当你在测试DAO组件的方法时,测试完成后方法的测试结果会自动回滚。

如果你确实想在测试DAO组件时,测试结束后提交事务,而不是回滚事务(默认设置)。
—— 只要将测试方法添加@Rollback(false)

★ 命名查询

甚至不再需要使用@Query注解
——只要让@NamedQuery或@NamedNativeQuery所定义的命名查询的查询名等于实体类的类名+DAO组件的查询方法的方法名
    中间以点号(.)隔开。


@NamedQuery或@NamedNativeQuery一般用在实体类上定义查询语句。


不难发现,命名查询与直接用@Query来定义查询的本质是一样,只不过它们定义SQL或JPQL语句的位置不同。

★ 自定义查询(全手动)

——Spring Data什么都不干,所有查询方法的方法体完全由开发者来实现。

▲ 自定义查询方法的设计(编程步骤)

(1) 让DAO组件接口额外继承一个自定义DAO接口
(2) 自定义DAO接口可以定义数据访问方法,再为该自定义DAO接口定义实现类、在该实现类中实现自定义的方法。

 Spring Data就能将自定义DAO接口的实现类中实现的查询方法“移植”给自己的DAO组件。


▲ 自定义查询方法的实现原理

DAO组件的实现类由Spring Data使用动态代理来动态生成的,因此DAO组件中所有查询方法的方法体都由Spring Data负责生成。

对于DAO接口中从父接口(自定义接口)中继承得到的方法,Spring Data会直接用其父接口的实现类所实现的查询方法作为其实现。

★ 样本查询

给Spring Data传入一个样本数据,Spring Data就能从数据库中查询出和样本相同的数据。

被查询的数据并不需要和样本是完全相同的,可能只需要和样本有几个属性是相同的。


▲ 样本查询的API(QueryByExampleExecutor):
JpaRepository继承了QueryByExampleExecutor接口,该接口提供了如下“样本查询”方法:

- <S extends T> Optional<S> findOne(Example<S> example);
- <S extends T> Iterable<S> findAll(Example<S> example);
- <S extends T> Iterable<S> findAll(Example<S> example, Sort sort);
- <S extends T> Page<S> findAll(Example<S> example, Pageable pageable);
- <S extends T> long count(Example<S> example);
- <S extends T> boolean exists(Example<S> example);

只要让DAO接口继承该QueryByExampleExecutor接口,DAO组件就可调用上面的样本查询方法。
——方法实现不要你操心,Spring Data会负责搞定它们。

▲ 创建Example

Example查询的关键在于Example参数,它提供了如下两个of()类方法来创建Example对象:

 - of(T probe):以probe对象创建最简单的Example对象,使用默认的匹配规则。
                要求被查询对象与样本对象所有属性都严格相等。

 - of(T probe, ExampleMatcher matcher):以probe创建Example对象,并使用matcher指定匹配规则。


▲ ExampleMatcher提供了如下静态方法来创建实例:
- static ExampleMatcher matching():创建一个需要所有属性都匹配的匹配器。 (and运算符)
- static ExampleMatcher matchingAll():完全等同于matching()方法
- static ExampleMatcher matchingAny():创建一个只要任意一个属性匹配的匹配器。(or运算符)


▲ ExampleMatcher还可通过如下方法来指定对特定属性的匹配规则: 

- withIgnoreCase():指定属性匹配时默认不区分大小写。
- withIgnoreCase(String... propertyPaths):指定propertyPaths参数列出的属性在匹配时不区分大小写。
- withIgnoreNullValues():指定不比较Example对象中属性值为null的属性。
- withIgnorePaths(String... ignoredPaths):指定忽略ignoredPaths参数列出的属性,也就是这些属性不参与匹配。
- withIncludeNullValues():强行指定要比较Example对象中属性值为null的属性。
- withMatcher(String propertyPath, 比较器):对propertyPath参数指定的属性使用专门的匹配规则。

 
▲ 样本查询的步骤:

(1) 让DAO接口要么继承JpaRepository(是QueryByExampleExecutor的子接口),或者增加继承QueryByExampleExecutor

(2) DAO组件可调用QueryByExampleExecutor的样本查询方法

★ Specification查询

它也是Spring Data提供的查询——是对JPA本身Criteria动态查询的包装。


▲ 为何要有动态查询

页面上常常会让用户添加不同的查询条件,程序就需要根据用户输入的条件,动态地组合不同的查询条件。

JPA为动态查询提供了Criteria查询支持。

Spring Data JPA则对Criteria查询进行了封装,封装之后的结果就是Specification查询。

——Specification查询比Jpa的Criteria动态查询更加简单。

▲ 核心API: JpaSpecificationExecutor

  • long count(Specification spec):返回符合Specification条件的实体的总数。
  • List findAll(Specification spec):返回符合Specification条件的实体。
  • Page findAll(Specification spec, Pageable pageable):返回符合Specification条件的实体,
    额外传入的Pageable参数用于控制排序和分页。
  • List findAll(Specification spec, Sort sort):返回符合Specification条件的实体,
    额外传入的Sort参数用于控制排序。
  • Optional findOne(Specification spec):返回符合Specification条件的单个实体,
    如果符合条件的实体有多个,该方法将会引发异常。
▲ Specification查询的步骤:

(1)让你的DAO接口继承JpaSpecificationExecutor。

(2)构建Specification对象,用于以面向对象的方式来动态地组合查询条件。
——最方面的地方(改进的地方),这一步就是为了解决动态拼接SQL的问题,而是改为使用面向对象的方式来组合查询条件。

▲ 如何创建Specification对象(用于组合多个查询条件)

- Specification参数用于封装多个代表查询条件的Predicate对象。

- Specification接口只定义了一个toPredicate()方法,该方法返回的Predicate对象就是Specification查询的查询条件,
  程序通常使用Lambda表达式来实现toPredicate()方法来定义动态查询条件。


▲ 还涉及如下两个API(本身就是在JPA的规范)

Predicate -  代表了单个查询条件,相当于sql语句的where子句中的单个的条件。也可用于组合多个查询条件。
CriteriaBuilder - 专门用于构建单个Predicate。


▲ 如何组合多个查询条件?

 两种方式:

  A - 用Specification的and或or来组合多个 Specification——每个Specification只组合一个查询条件。

  B - 先用CriteriaBuilder的and或or来组合多个Predicate对象,得到一个最终的Predicate,然后再将Predicate包装成Specification。

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

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

相关文章

大数据技术之Hadoop:HDFS集群安装篇(三)

目录 分布式文件系统HDFS安装篇 一、为什么海量数据需要分布式存储 二、 分布式的基础架构分析 三、 HDFS的基础架构 四 HDFS集群环境部署 4.1 下载安装包 4.2 集群规划 4.3 上传解压 4.4 配置HDFS集群 4.5 准备数据目录 4.6 分发hadoop到其他服务器 4.7 配置环境变…

C# Equals()方法报错:NullReferenceException was unhandled

下面是一个C# Equals()方法的例子&#xff0c;执行时报错了 static void Main(string[] args) {string name "sandeep";string myName null;Console.WriteLine(" operator result is {0}", name myName);Console.WriteLine("Equals method result…

Redis探索之旅

目录 今日良言&#xff1a;有志者自有千计万计&#xff0c;无志者只感千难万难 一、简介 二、Redis的安装 三、Redis的简单使用 四、Redis相关知识点 1.缓存分类 2.五大基本数据类型使用 3.持久化 4.常见面试题 今日良言&#xff1a;有志者自有千计万计&#xff0c;无…

音视频 FFmpeg命令行搭建

文章目录 一、配置二、测试 一、配置 以FFmpeg4.2.1 win32为例 解压ffmpeg-4.2.1-win32-shared.zip 拷⻉可执⾏⽂件到C:\Windows拷⻉动态链接库到C:\Windows\SysWOW64 注&#xff1a;WoW64 (Windows On Windows64)是⼀个Windows操作系统的⼦系统&#xff0c;被设计⽤来处理许…

【机器学习1】什么是机器学习机器学习的重要性

什么是机器学习? 简而言之&#xff0c;机器学习就是训练机器去学习。 机器学习作为人工智能(Artificial Intelligence,AI)的一个分支&#xff0c;以其最基本的形式来使用算法通过从数据中获取知识来进行预测。 不同于人类通过分析大量数据手动推导规则和模型&#xff0c;机…

24届近5年上海交通大学自动化考研院校分析

今天给大家带来的是上海交通大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、上海交通大学 学校简介 上海交通大学是我国历史最悠久、享誉海内外的高等学府之一&#xff0c;是教育部直属并与上海市共建的全国重点大学。经过120多年的不懈努力&#xff0c;上海交…

Jenkins集成appium自动化测试(Windows篇)

一&#xff0c;引入问题 自动化测试脚本绝大部分用于回归测试&#xff0c;这就需要制定执行策略&#xff0c;如每天、代码更新后、项目上线前定时执行&#xff0c;才能达到最好的效果&#xff0c;这时就需要进行Jenkins集成。 不像web UI自动化测试可以使用无痕浏览器做到无界…

Vc - Qt - QPainter translate

QPainter的translate()函数是用来对绘制坐标系统进行平移操作的方法。它可以将绘制的原点&#xff08;坐标轴的起始点&#xff09;在水平和垂直方向上进行平移。以下是一个使用QPainter的translate()方法进行坐标平移的示例代码&#xff1a; QPainter painter(this);// 绘制一个…

Python爬虫的Selenium(学习于b站尚硅谷)

目录 一、Selenium  1.为什么要学习Selenium  &#xff08;1&#xff09;什么是Selenium  &#xff08;2&#xff09;为什么使用selenium?  &#xff08;3&#xff09;代码演示 2. selenium的基本使用  &#xff08;1&#xff09;如何安装selenium  &#xff08;2…

有哪些pdf修改方法?这几种方法学会就够了

有哪些pdf修改方法&#xff1f;PDF是一种非常常见的电子文档格式&#xff0c;它有很多优点&#xff0c;例如可读性强、易于保护、易于打印等等。但是&#xff0c;有时候我们需要对PDF进行修改&#xff0c;例如添加、删除或修改文本、更改图片、合并或分割文件等等。那么今天就给…

mysql_docker主从复制_实战_binlog混合模式_天座著

步骤1&#xff1a;拉取镜像 docker pull mariadb:latest 步骤2.1&#xff1a;创建两个文件夹用于放置挂载mysql的my.cnf /tianzuomysqlconf/master /tianzuomysqlconf/slave mkdir /tianzuomysqlconf cd /tianzuomysqlconf mkdir master mkdir slave 步骤2.2&#xff1a;创…

Python 开发工具 Pycharm —— 使用技巧Lv.2

pydoc是python自带的一个文档生成工具&#xff0c;使用pydoc可以很方便的查看类和方法结构 本文主要介绍&#xff1a;1.查看文档的方法、2.html文档说明、3.注释方法、 一、查看文档的方法 **方法1&#xff1a;**启动本地服务&#xff0c;在web上查看文档 命令【python3 -m…

剑指Offer12.矩阵中的路径 C++

1、题目描述 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平…

关于Express 5

目录 1、概述 2、Express 5的变化 2.1 弃用或删除内容的列表&#xff1a; app.param&#xff08;name&#xff0c;fn&#xff09;名称中的前导冒号&#xff08;&#xff1a;&#xff09; app.del() app.param&#xff08;fn&#xff09; 复数方法名 res.json&#xff0…

Python批量查字典和爬取双语例句

最近&#xff0c;有网友反映&#xff0c;我的批量查字典工具换到其它的网站就不好用了。对此&#xff0c;我想说的是&#xff0c;互联网包罗万象&#xff0c;网站的各种设置也有所不同&#xff0c;并不是所有的在线字典都可以用Python爬取的。事实上&#xff0c;很多网站为了防…

计算机是怎么存储和识别人类高级语言的

目录 1、计算机是怎么“存储”人类的高级语言的&#xff1f;2、 UTF-8和UTF-32的区别3、UTF-8是如何区分字节的长度呢&#xff1f;&#xff08;即如何识别这一串二进制是多少个字节的&#xff1f;&#xff09;4、计算机是如何识别人类的高级语言的&#xff1f; 1、计算机是怎么…

八、复用(1)

本章概要 组合语法继承语法 初始化基类带参数的构造函数 委托 代码复用是面向对象编程&#xff08;OOP&#xff09;最具魅力的原因之一。 对于像 C 语言等面向过程语言来说&#xff0c;“复用”通常指的就是“复制代码”。任何语言都可通过简单复制来达到代码复用的目的&#…

使用JProfiler进入JVM分析

要评测JVM&#xff0c;必须将JProfiler的评测代理加载到JVM中。这可以通过两种不同的方式发生&#xff1a;在启动脚本中指定-agentpath VM参数&#xff0c;或者使用attach API将代理加载到已经运行的JVM中。 JProfiler支持这两种模式。添加VM参数是评测的首选方式&#xff0c;集…

【MMU】认识 MMU 及内存映射的流程

MMU&#xff08;Memory Manager Unit&#xff09;&#xff0c;是内存管理单元&#xff0c;负责将虚拟地址转换成物理地址。除此之外&#xff0c;MMU 实现了内存保护&#xff0c;进程无法直接访问物理内存&#xff0c;防止内存数据被随意篡改。 目录 一、内存管理体系结构 1、…

openssl安装问题合辑

1.openssl拖累nginx编译失败 问题描述&#xff1a; 因为漏洞原因&#xff0c;升级openssl之后需要重新编译nginx&#xff0c;进行了以下步骤&#xff1a; config没问题&#xff0c;但是make一直报错 初步判断是openssl安装有问题&#xff0c;原因不明&#xff0c;重装了opens…
最新文章