68、Spring Data JPA 的 方法名关键字查询
★ 方法名关键字查询(全自动)
(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属性大于指定值的记录。
▲ 关键字方法中同样可定义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。
代码演示:
数据库数据

创建对应的两个实体类。
Student实体类
这节用到的一些类和配置文件

Clazz 实体类

//根据班级名称查询对象–ClazzDao
方法

测试结果

//根据班级名称模糊查询–ClazzDao
方法:

测试结果

查询年龄大于指定参数的学生–StudentDao
方法:

测试结果:

根据年龄和班级名称查询学生–StudentDao

方法:

测试结果:

根据地址后缀进行分页查询,查询 address 带有 “洞” 的学生并进行分页 – StudentDao

结果:


完整代码
Student
package cn.ljh.app.domain;import lombok.Getter;
import lombok.Setter;import javax.persistence.*;/*** strategy:策略 , GenerationType:生成类型 , Column:列*///修饰该类成为实体类
@Entity
@Getter
@Setter
//表示该类映射到数据库的student_inf表
@Table(name = "student_inf")
public class Student
{@Id //设置为主键@GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增策略@Column(name = "student_id") //该属性名映射到数据库表的列名private Integer id;private String name;private int age;private String address;private char gender;//关联关系,多个学生对应一个教室//targetEntity:指定关联实体的类型,不指定也没问题,底层会通过反射去识别@ManyToOne(targetEntity = Clazz.class)//JoinColumn: name = "clazz_code" ,映射外键列列名 ,这个"clazz_code "是指映射的 Clazz 类中的成员变量//referencedColumnName = "clazz_code" ,这个"clazz_code" 是指表的列名//referencedColumnName: --> name = "clazz_code"这个外键列名引用到对方的数据表(clazz_inf)的列名叫"clazz_code"@JoinColumn(name = "clazz_code",referencedColumnName = "clazz_code")private Clazz clazz;@Overridepublic String toString(){return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", address='" + address + '\'' +", gender=" + gender +'}';}
}
Clazz
package cn.ljh.app.domain;import lombok.Getter;
import lombok.Setter;import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;@Entity //修饰该类为实体类
@Table(name = "clazz_inf") //该实体类映射到数据库的 clazz_inf 表
@Getter
@Setter
public class Clazz
{@Id//主键id@Column(name = "clazz_code") //表示这个属性在数据库表中的列名叫这个clazz_code@GeneratedValue(strategy = GenerationType.IDENTITY) //主键id的自增策略private Integer clazz_code; //班级号private String name; //班级名称//关联关系,一个教室对应多个学生//targetEntity:指定关联实体的类型,不指定也没问题,底层会通过反射去识别//mappedBy 属性(clazz) 关联实体(Student)中,哪个属性(student.clazz)引用到当前实体(Student实体)@OneToMany(targetEntity = Student.class,mappedBy = "clazz")private Set<Student> students = new HashSet<>();@Overridepublic String toString(){return "Clazz{" +"clazz_code=" + clazz_code +", name='" + name + '\'' +'}';}
}
ClazzDao
package cn.ljh.app.dao;import cn.ljh.app.domain.Clazz;
import org.springframework.data.repository.CrudRepository;import java.util.List;//CrudRepository 的第一个泛型参数是被操作的实体类型,第二个参数是实体的主键类型
//方法名关键字查询: Spring Data 会自动生成查询语句、生成查询方法体
public interface ClazzDao extends CrudRepository<Clazz, Integer>
{//根据班级名称查询对象Clazz findByName(String name);//根据班级名称模糊查询List<Clazz> findByNameLike(String namePattern);}
StudentDao
package cn.ljh.app.dao;import cn.ljh.app.domain.Student;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;import java.util.List;//CrudRepository 的第一个泛型参数是被操作的实体类型,第二个参数是实体的主键类型
public interface StudentDao extends CrudRepository<Student,Integer>
{//查询年龄大于指定参数的学生List<Student> findByAgeGreaterThan(int startAge);//根据年龄和班级名称查询学生//Age 和 ClazzName 用 And 连接起来,表示两个查询条件,//ClazzName这两个单词中间没有And连接起来,表示是一个路径写法,表示是Clazz类的name属性List<Student> findByAgeAndClazzName(int age , String clazzName);//根据地址后缀进行分页查询,查询 address 带有 "洞" 的学生并进行分页Page<Student> findByAddressEndingWith(String addrSuffix, Pageable pageable);}
ClazzDaoTest
package cn.ljh.app.dao;import cn.ljh.app.domain.Clazz;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;//SpringBootTest.WebEnvironment.NONE : 表示不需要web环境
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class ClazzDaoTest
{@Autowiredprivate ClazzDao clazzDao;//参数化测试@ParameterizedTest//参数只有一个的测试用 @ValueSource//根据班级名称查询对象@ValueSource(strings = {"超级A营","超级B班","aaa"})public void testFindByName(String name){Clazz clazz = clazzDao.findByName(name);System.err.println(clazz);}@ParameterizedTest//根据班级名称模糊查询@ValueSource(strings = {"超级%","%营"})public void testFindByNameLike(String namePattern){List<Clazz> clazzes = clazzDao.findByNameLike(namePattern);clazzes.forEach(System.err::println);}}
StudentDaoTest
package cn.ljh.app.dao;import cn.ljh.app.domain.Student;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;import java.util.List;//SpringBootTest.WebEnvironment.NONE : 表示不需要web环境
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class StudentDaoTest
{@Autowiredprivate StudentDao studentDao;/*** @ValueSource: 每次只能传一个参数* @CsvSource:每次可以传多个参数*///需求:查询年龄大于指定参数的记录//参数化测试@ParameterizedTest@ValueSource(ints = {20, 200})public void testFindByAgeGreaterThan(int startAge){List<Student> students = studentDao.findByAgeGreaterThan(startAge);students.forEach(System.err::println);}//根据年龄和班级名称查询学生//Age 和 ClazzName 用 And 连接起来,表示两个查询条件,//ClazzName这两个单词中间没有And连接起来,表示是一个路径写法,表示是Clazz类的name属性@ParameterizedTest//参数一个是int,一个是String,这个注解在传参的时候会自动进行类型转换@CsvSource(value = {"20,超级A营", "18,超级D班"})public void testFindByAgeAndClazzName(int age, String clazzName){List<Student> students = studentDao.findByAgeAndClazzName(age, clazzName);students.forEach(System.err::println);}//pageNo: 要查询哪一页的页数 , pageSize: 每页显示的条数@ParameterizedTest@CsvSource({"洞,2,3","洞,1,4","洞,3,2"})public void testFindByAddressEndingWith(String addrSuffix, int pageNo, int pageSize){//分页对象,此处的pageNo是从0开始的,0代表第一页,所以这里的 pageNo 要 -1Pageable pageable1 = PageRequest.of(pageNo - 1, pageSize);Page<Student> students = studentDao.findByAddressEndingWith(addrSuffix, pageable1);int number = students.getNumber() + 1;System.err.println("总页数:" + students.getTotalPages());System.err.println("总条数:" + students.getTotalElements());System.err.println("当前第:" + number + " 页");System.err.println("当前页有:" + students.getNumberOfElements() + " 条数据");students.forEach(System.err::println);}
}
application.properties
# 配置连接数据源,这些配置由 DataSourceProperties 类负责处理---
# SpringBoot 读取到这些配置信息后,会使用 AutoConfiguration 去容器中自动配置 DataSource Bean
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456# 针对 HikariCP 进行详细配置---
# 指定连接池最大只能有20个连接
#spring.datasource.hikari.maximum-pool-size=20# 配置 JPA 相关属性,由 JpaProperties 类负责处理---
# SpringBoot 读取到这些配置信息后,会使用 AutoConfiguration 去容器中自动配置 EntityManagerFactory Bean
# JPA 底层就是依赖这个 EntityManagerFactory# 自动建表,只能true或者false
# spring.jpa.generate-ddl=true
# 这个也是自动建表,不过比spring.jpa.generate-ddl更严谨,作用:如果已有数据表,无需创建,否则创建数据表
spring.jpa.hibernate.ddl-auto=update
# 指定操作的数据库
spring.jpa.database=mysql
# 是否在执行的时候显示sql语句
spring.jpa.show-sql=true
db.sql
drop database springboot;
create database springboot;
use springboot;
-- 创建clazz_inf表
create table clazz_inf
(clazz_code int primary key auto_increment,name varchar(255)
);
-- 创建student_inf表
create table student_inf
(student_id int primary key auto_increment,name varchar(255),age int,address varchar(255),gender char(2),clazz_code int,foreign key(clazz_code) references clazz_inf(clazz_code)
);
-- 向clazz_inf表插入数据
insert into clazz_inf
values
(null, '疯狂Java训练营'),
(null, '疯狂Java就业班'),
(null, '疯狂Java基础班'),
(null, '疯狂Java提高班');-- 向student_inf表插入数据
insert into student_inf
values
(null, '孙悟空', 500, '花果山水帘洞', '男', 1),
(null, '牛魔王', 800, '积雷山摩云洞', '男', 1),
(null, '猪八戒', 600, '福陵山云栈洞', '男', 2),
(null, '沙和尚', 580, '流沙河', '男', 3),
(null, '白鼠精', 23, '陷空山无底洞', '女', 2),
(null, '蜘蛛精', 18, '盘丝岭盘丝洞', '女', 4),
(null, '玉面狐狸', 21, '积雷山摩云洞', '女', 3),
(null, '杏仙', 19, '荆棘岭木仙庵', '女', 4);
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version></parent><groupId>cn.ljh</groupId><artifactId>spring_data_jpa_keyword</artifactId><version>1.0.0</version><name>spring_data_jpa_keyword</name><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>相关文章:
68、Spring Data JPA 的 方法名关键字查询
★ 方法名关键字查询(全自动) (1)继承 CrudRepository 接口 的 DAO 组件可按特定规则来定义查询方法,只要这些查询方法的 方法名 遵守特定的规则,Spring Data 将会自动为这些方法生成 查询语句、提供 方法…...
Brother CNC联网数采集和远程控制
兄弟CNC IP地址设定参考:https://www.sohu.com/a/544461221_121353733没有能力写代码的兄弟可以提前下载好网络调试助手NetAssist,这样就不用写代码来测试连接CNC了。 以上是网络调试助手抓取CNC的产出命令,结果有多个行string需要自行解析&…...
Jenkins 编译 Maven 项目提示错误 version 17
在最近使用集成工具的时候,对项目进行编译提示下面的错误信息: maven-compiler-plugin:3.11.0:compile (default-compile) on project mq-service: Fatal error compiling: error: release version 17 not supported 问题和解决 上面提示的错误信息原…...
数据结构——排序算法——堆排序
堆排序过程如下: 1.用数列构建出一个大顶堆,取出堆顶的数字; 2.调整剩余的数字,构建出新的大顶堆,再次取出堆顶的数字; 3.循环往复,完成整个排序。 构建大顶堆有两种方式: 1.从 0 开…...
【Spring事务底层实现原理】
Transactional注解 Spring使用了TransactionInterceptor拦截器,该拦截器主要负责事务的管理,包括开启、提交、回滚等操作。当在方法上添加Transactional注解时,Spring会在AOP框架中对该方法进行拦截,TransactionInterceptor会在该…...
docker快速安装redis,mysql,minio,nacos等常用软件【持续更新】
redis ①拉取镜像 docker pull redis② 创建容器 docker run -d --name redis --restartalways -p 6379:6379 redis --requirepass "PASSWORD"–requirepass “输入你的redis密码” nacos ①:docker拉取镜像 docker pull nacos/nacos-server:1.2.0②…...
SCRUM产品负责人(CSPO)认证培训课程
课程简介 Scrum是目前运用最为广泛的敏捷开发方法,是一个轻量级的项目管理和产品研发管理框架。产品负责人是Scrum的三个角色之一,产品负责人在Scrum产品开发当中扮演舵手的角色,他决定产品的愿景、路线图以及投资回报,他需要回答…...
python连接mysql数据库的练习
一、导入pandas内置的sqlite3模块,连接的信息:ip地址是本机, 端口号port 是3306, 用户user是root, 密码password是123456, 数据库database是lambda-xiaozhang import pymysql# 打开数据库连接,参数1:主机名或IP;参数…...
扩散模型在图像生成中的应用:从真实样例到逼真图像的奇妙转变
一、扩散模型 扩散模型的起源可以追溯到热力学中的扩散过程。热力学中的扩散过程是指物质从高浓度往低浓度的地方流动,最终达到一种动态的平衡。这个过程就是一个扩散过程。 在深度学习领域中,扩散模型(diffusion models)是深度生…...
Windows 打包 Docker 提示环境错误: no DOCKER_HOST environment variable
这个问题应该还是比较常见的。 [ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.40.2:build (default) on project mq-service: Execution default of goal io.fabric8:docker-maven-plugin:0.40.2:build failed: No <dockerHost> given, no DOCKER_H…...
2023.9.8 基于传输层协议 UDP 和 TCP 编写网络通信程序
目录 UDP 基于 UDP 编写网络通信程序 服务器代码 客户端代码 TCP 基于 TCP 编写网络通信程序 服务器代码 客户端代码 IDEA 打开 支持多客户端模式 UDP 特点: 无连接性:发送端和接收端不需要建立连接也可相互通信,且每个 UDP 数据包都…...
单例模式,适用于对象唯一的情景(设计模式与开发实践 P4)
文章目录 单例模式实现代理单例惰性单例 上一章后续的内容是关于 JS 函数闭包的,考虑很多读者已经有了闭包基础或者希望通过实战理解,遂跳过上一章直接开始设计模式篇~ 需要注意的是,代码部分仅供参考,主要关注的内容是…...
C语言实现三子棋游戏(详解)
目录 引言: 1.游戏规则: 2.实现步骤: 2.1实现菜单: 2.2创建棋盘并初始化: 2.3绘制棋盘: 2.4玩家落子: 2.5电脑落子: 2.6判断胜负: 3.源码: 结语&…...
javaee之黑马乐优商城3
异步查询工具axios(儿所以时) vue官方推荐的ajax请求框架 新增品牌页面 如何找到上面这个页面 下面这个页面里面的新增商品弹窗 上面就是请求路径与请求方式 那么请求参数是什么? brand对象,外加商品分类的id数组cids (这里其实不止就是添加…...
Pytorch intermediate(二) ResNet
实现了残差网络,残差网络结构。代码比之前复杂很多 conv3x3:将输入数据进行一次卷积,将数据转换成为,残差块需要的shape大小 ResidualBlock:残差块,也是所谓的恒等块。为什么被称为恒等块,大概…...
【2023集创赛】加速科技杯作品:高光响应的二硫化铼光电探测器
本文为2023年第七届全国大学生集成电路创新创业大赛(“集创赛”)加速科技杯西北赛区二等奖作品分享,参加极术社区的【有奖征集】分享你的2023集创赛作品,秀出作品风采,分享2023集创赛作品扩大影响力,更有丰…...
编写postcss插件,全局css文件px转vw
跟目录下创建plugins文件夹,创建postcss-px-to-viewport.ts文件 文件内代码: // postcss 的插件 vite内置了postCss插件 无需安装 import { Plugin } from postcss;interface Options {viewportWidth: number }const Options {viewportWidth: 375, // …...
精品SpringCloud的B2C模式在线学习网微服务分布式
《[含文档PPT源码等]精品基于SpringCloud实现的B2C模式在线学习网站-微服务-分布式》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具: 开发语言:Java 框架:springcloud JDK版本…...
解决vue项目导出当前页Table为Excel
解决vue项目中导出当前页表格为Excel表格的方案 用到的技术: Vue2Element-uifile-saverxlsx 1、创建vue项目,安装element-ui 2、创建一个组件,组件内放入表格,和导出按钮 <template><div><!-- 导出的按钮 -->…...
C++设计模式_04_Strategy 策略模式
接上篇,本篇将会介绍C设计模式中的Strategy 策略模式,和上篇模板方法Template Method一样,仍属于“组件协作”模式,它与Template Method有着异曲同工之妙。 文章目录 1. 动机( Motivation)2. 代码演示Stra…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
