95、Spring Data Redis 之使用RedisTemplate 实现自定义查询 及 Spring Data Redis 的样本查询

Spring Data Redis 之使用RedisTemplate 实现自定义查询

Book实体类
在这里插入图片描述

原本的接口,再继承我们自定义的接口
在这里插入图片描述

自定义查询接口----CustomBookDao

在这里插入图片描述

实现类:CustomBookDaoImpl

1、自定义添加hash对象的方法

在这里插入图片描述


2、自定义查询价格高于某个点的Book对象

在这里插入图片描述


测试:自定义添加hash对象的方法

在这里插入图片描述
成功添加hash对象到redis数据库
在这里插入图片描述

测试:自定义查询价格高于某个点的Book对象

在这里插入图片描述
结果:
数据:价格有100, 200 ,300这三个
在这里插入图片描述
结果正确,因为自定义的查询,是价格 > , 不是 >= 。
在这里插入图片描述




Spring Data Redis 的样本查询

如图:因为bookDao有继承这个 QueryByExampleExecutor 接口,所以可以进行样本查询
在这里插入图片描述

样本中只有 name 作为参数来查询
在这里插入图片描述

样本中只有 author 作为参数来查询
在这里插入图片描述

完整代码

Book

package cn.ljh.app.domain;import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.TimeToLive;
import org.springframework.data.redis.core.index.Indexed;import java.util.concurrent.TimeUnit;//通过@RedisHash注解存储实体Book到redis,就是该Book对象将存储为books(key)对应的hash对象(value) ---> key(books) field value
//相当于 @Entity 实体类映射到数据库,这里的RedisHash就是把这个book存到redis中
@RedisHash("books")
@Data
public class Book
{@Idprivate Integer id; //即使这里类型是Integer,可是存到redis后,也会变成String类型//Indexed 指定对普通类型的属性建立索引,索引化后的属性才可用于查询。@Indexedprivate String name;@Indexedprivate String author;private double price;//该注解修饰一个数值类型的属性,用于指定该对象的过期时长。@TimeToLive(unit = TimeUnit.MINUTES)private long ttl;public Book(){}public Book(Integer id, String name, double price, String author){this.id = id;this.name = name;this.price = price;this.author = author;}public Book(Integer id, String name, double price, String author, long ttl){this.id = id;this.name = name;this.price = price;this.author = author;this.ttl = ttl;}
}

BookDao

package cn.ljh.app.dao;import cn.ljh.app.domain.Book;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;import java.util.List;//DAO接口只需继承CrudRepository,Spring Data Redis 就能为DAO组件提供实现类。
//参数1:要操作的实体的类型  参数2:Id类型
//继承这个 QueryByExampleExecutor 接口,才可以进行样本查询
public interface BookDao extends CrudRepository<Book, Integer>, QueryByExampleExecutor,CustomBookDao
{//方法名关键字查询//根据 name 查询Book对象//Booke实体类中的 name 属性有添加注解 @Indexed,所以可以对这个属性作为key进行查询List<Book> findByName(String name);//根据 author 查询Book对象//这个author在实体类中也有添加 @Indexed 注解List<Book> findByAuthor(String author);}

CustomBookDao

package cn.ljh.app.dao;import cn.ljh.app.domain.Book;import java.util.List;
import java.util.Map;//自定义查询
public interface CustomBookDao
{//自定义添加hash对象的方法void hmset(String key, Map<String,String> value);//自定义查询价格高于某个点的Book对象List<Book> findByPriceGt(double startPrice);}

CustomBookDaoImpl

package cn.ljh.app.dao.impl;import cn.ljh.app.dao.CustomBookDao;
import cn.ljh.app.domain.Book;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.StringRedisTemplate;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;//自定义查询接口实现类
public class CustomBookDaoImpl implements CustomBookDao
{//借助于自动配置的 StringRedisTemplate 来实现数据库的访问private final StringRedisTemplate stringRedisTemplate;//有参构造器进行依赖注入public CustomBookDaoImpl(StringRedisTemplate stringRedisTemplate){this.stringRedisTemplate = stringRedisTemplate;}//自定义添加hash对象的方法@Overridepublic void hmset(String key, Map<String, String> value){//调用 HashOperations 的方法来向数据库中存入 Hash 对象//要操作的value的类型是hash对象,就用.opsForHash() 方法stringRedisTemplate.opsForHash().putAll(key, value);}//自定义查询价格高于某个点的Book对象@Overridepublic List<Book> findByPriceGt(double startPrice){//由于 price 没有用注解@Indexed 建立索引,因此不能直接根据price来查询//首先获取全部的Book对象,redis会自动把我们添加的所有Book对象中的id,都存在一个set集合里面,因此先把id从set集合中都拿出来//要操作的value的类型是 set 集合,就用.opsForSet() 方法,此处的 books 就是 Book对象上 @RedisHash("books") 所指定的keySet<String> idSet = this.stringRedisTemplate.opsForSet().members("books");//把这个 HashOperations 先提取出来HashOperations<String, String, String> hashOps = this.stringRedisTemplate.opsForHash();//返回接收Book对象的集合List<Book> bookList = new ArrayList<>();//2、遍历id集合,根据id获取所有的实体对象Bookfor (String id : idSet){//key 为 "books:<id值>" 对应的hash对象,就保存着一个个的持久化对象的全部信息。String objkey = "books:" + id;//3、判断key是否存在,因为key即使过期了,也还记录者,该objkey对应的value还存在,那么说明该实体还存在if (this.stringRedisTemplate.hasKey(objkey)){//获取 "books:"+id 的key所对应的 Hash 对象中的price属性--就是Book对象的price属性double price = Double.parseDouble(hashOps.get(objkey, "price"));//4、判断价格,符合条件的再添加到list集合中if (price > startPrice){bookList.add(new Book(Integer.parseInt(hashOps.get(objkey, "id")),hashOps.get(objkey, "name"),price,hashOps.get(objkey, "author")));}}}return bookList;}
}

BookDaoTest

//=========================================样本查询=========================================@Autowiredprivate BookDao bookDao;//==========================自定义查询================================//自定义添加hash对象的方法@Testpublic void testHmset(){bookDao.hmset("test", Map.of("k1", "value1", "k2", "value2"));}//自定义查询价格高于某个点的Book对象@ParameterizedTest@ValueSource(doubles = {100, 200, 300})public void testFindByPriceGt(double startPrice){List<Book> books = bookDao.findByPriceGt(startPrice);books.forEach(System.out::println);}//=========================================样本查询=========================================//样本中只有 name 作为参数来查询@ParameterizedTest@ValueSource(strings = {"七龙珠", "火影忍者"})public void testFindByExampleOnlyName(String name){//创建一个样本对象Example ex = Example.of(new Book(null, name, 0, null),ExampleMatcher.matching()//忽略样本对象中的所有null值,即null值不作为样本的比较属性.withIgnoreNullValues()//因为查询的参数只有name,所以price不参与比较,用这个方法把这个price忽略掉//因为price的默认值是0,不是null,需要额外用这个方法.withIgnorePaths("price"));//查询所有对象,把样本作为条件参数传进去比较查询Iterable books = bookDao.findAll(ex);books.forEach(System.err::println);}//样本中只有 author 作为参数来查询@ParameterizedTest@ValueSource(strings = "鸟山明")public void testFindByExampleOnlyAuthor(String author){//先创建一个样本Example<Book> bookExample = Example.of(new Book(null, null, 0, author),ExampleMatcher.matching().withIgnoreNullValues().withIgnorePaths("price"));//查询所有对象,把样本作为条件参数传进去比较查询bookDao.findAll(bookExample).forEach(System.err::println);}

application.properties

# 配置连接redis服务器的相关信息
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
# 选择连接redis默认16个数据库中的第11个数据库
spring.redis.database=11
# 连接redis超时的时间--30秒
spring.redis.connect-timeout=30s# 配置连接池的相关信息
# 配置这个连接池最大的连接数量
spring.redis.lettuce.pool.max-active=10
# 配置最大的能有多少个活动的、空闲的连接数量  idle-空闲
spring.redis.jedis.pool.max-idle=10

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>redis_boot</artifactId><version>1.0.0</version><name>redis_boot</name><properties><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 配置连接池需要的依赖 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.9.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JavaEE】线程安全的集合类

文章目录 前言多线程环境使用 ArrayList多线程环境使用队列多线程环境使用哈希表1. HashTable2. ConcurrentHashMap 前言 前面我们学习了很多的Java集合类&#xff0c;像什么ArrayList、Queue、HashTable、HashMap等等一些常用的集合类&#xff0c;之前使用这些都是在单线程中…

RabbitMQ之Fanout(扇形) Exchange解读

目录 基本介绍 适用场景 springboot代码演示 演示架构 工程概述 RabbitConfig配置类&#xff1a;创建队列及交换机并进行绑定 MessageService业务类&#xff1a;发送消息及接收消息 主启动类RabbitMq01Application&#xff1a;实现ApplicationRunner接口 基本介绍 Fa…

使用华为eNSP组网试验⑸-访问控制

今天练习使用华为sNSP模拟网络设备上的访问控制&#xff0c;这样的操作我经常在华为的S7706、S5720、S5735或者H3C的S5500、S5130、S7706上进行&#xff0c;在网络设备上根据情况应用访问控制的策略是一个网管必须熟练的操作&#xff0c;只是在真机上操作一般比较谨慎&#xff…

微服务技术栈-Gateway服务网关

文章目录 前言一、为什么需要网关二、Spring Cloud Gateway三、断言工厂和过滤器1.断言工厂2.过滤器3.全局过滤器4.过滤器执行顺序 四、跨域问题总结 前言 在之前的文章中我们已经介绍了微服务技术中eureka、nacos、ribbon、Feign这几个组件&#xff0c;接下来将介绍另外一个组…

Android源码下载

文章目录 一、Android源码下载 一、Android源码下载 AOSP 是 Android Open Source Project 的缩写。 git 常用命令总结 git 远程仓库相关的操作 # 查看 remote.origin.url 配置项的值 git config --list Android9.0之前代码在线查看地址&#xff1a;http://androidxref.com/ …

【LeetCode高频SQL50题-基础版】打卡第2天:第11-15题

文章目录 【LeetCode高频SQL50题-基础版】打卡第2天&#xff1a;第11-15题⛅前言 员工奖金&#x1f512;题目&#x1f511;题解 学生们参加各科测试的次数&#x1f512;题目&#x1f511;题解 至少有5名直接下属的经理&#x1f512;题目&#x1f511;题解 确认率&#x1f512;题…

使用python利用merge+sort函数对excel进行连接并排序

好久没更新了&#xff0c;天天玩短视频了。现在发现找点学习资料真的好难。 10.1期间偶然拿到一本书 本书是2022年出版的&#xff0c;看了一下不错&#xff0c;根据上面的案例结合&#xff0c;公司经营整合案例&#xff0c;分享一下。 数据内容来源于书中内容&#xff0c;仅供…

docker部署Vaultwarden密码共享管理系统

Vaultwarden是一个开源的密码管理器&#xff0c;它是Bitwarden密码管理器的自托管版本。它提供了类似于Bitwarden的功能&#xff0c;允许用户安全地存储和管理密码、敏感数据和身份信息。 Vaultwarden的主要特点包括&#xff1a; 1. 安全的数据存储&#xff1a;Vaultwarden使…

手机投屏电脑软件AirServer5.6.3.0最新免费版本下载

随着智能手机的普及&#xff0c;越来越多的人喜欢用手机观看视频、玩游戏、办公等。但是&#xff0c;有时候手机屏幕太小&#xff0c;不够清晰&#xff0c;也不方便操作。这时候&#xff0c;如果能把手机屏幕投射到电脑上&#xff0c;就可以享受更大的视野&#xff0c;更流畅的…

【javaweb】学习日记Day11 - tlias智能管理系统 - 文件上传 新增 修改员工 配置文件

目录 一、员工管理功能开发 1、新增员工 postman报错500的原因 &#xff08;1&#xff09;Controller类 &#xff08;2&#xff09;Service类 &#xff08;3&#xff09;Mapper类 2、根据ID查询 &#xff08;1&#xff09;Controller类 &#xff08;2&#xff09;Serv…

基于小波神经网络的网络流量预测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022A 3.部分核心程序 ........................................................... %% 总流量数据 input(:,1)dat…

如何保证 RabbitMQ 的消息可靠性?

项目开发中经常会使用消息队列来完成异步处理、应用解耦、流量控制等功能。虽然消息队列的出现解决了一些场景下的问题&#xff0c;但是同时也引出了一些问题&#xff0c;其中使用消息队列时如何保证消息的可靠性就是一个常见的问题。如果在项目中遇到需要保证消息一定被消费的…

(高阶) Redis 7 第18讲 RedLock 分布式锁

🌹 以下分享 RedLock 分布式锁,如有问题请指教。🌹🌹 如你对技术也感兴趣,欢迎交流。🌹🌹🌹 如有对阁下帮助,请👍点赞💖收藏🐱‍🏍分享😀 问题 分布式锁问题从(高阶) Redis 7 第17讲 分布式锁 实战篇_PJ码匠人的博客-CSDN博客 这篇文章来看,…

redis学习(二)——redis常见命令及基础数据类型

数据类型 基础数据类型 字符串 String abcMap集合 Hsah {name:“zhangsan”,age:18}列表 List [a, b, c, d]Set集合 Set {a,b,c}有序Set集合 SortSet {a:1,b:2,c:3} 特殊数据类型 GEO 地理坐标 {A:(100.2,35.1)}BitMap 位图&#xff0c;只存储0和1 01101011101HyperLog 基数…

地图资源下载工具数据在线、离线查询及数据激活功能

哨兵相关产品&#xff0c;工具提供了表示系统是否为归档离线的信息&#xff01;您可以利用下载[定时重试]功能激活并下载哨兵相关离线产品数据&#xff01;

Java中栈实现怎么选?Stack、Deque、ArrayDeque、LinkedList(含常用Api积累)

目录 Java中的Stack类 不用Stack有以下两点原因 1、从性能上来说应该使用Deque代替Stack。 2、Stack从Vector继承是个历史遗留问题&#xff0c;JDK官方已建议优先使用Deque的实现类来代替Stack。 该用ArrayDeque还是LinkedList&#xff1f; ArrayDeque与LinkList区别&#xff1…

Java-多线程

摘要 多线程编程是现代软件开发中的一个重要概念&#xff0c;它允许程序同时执行多个任务&#xff0c;提高了程序的性能和响应性。本博客深入探讨了多线程编程的关键概念、原理和最佳实践。 线程、进程、多线程、并发、并行 进程 进程是计算机中运行的程序的实例。每次打开一…

《人间失格》阅读笔记

《人间失格》读书笔记 2023年10月7日读完&#xff0c;在过去的三个月时间内&#xff0c;有忙碌申博、从杭州辞职回家、准备入学、到澳门入学的事情&#xff0c;终于忙完了这些所有事情&#xff0c;回到了横琴的小房子里读完了这本书。 这本书前半部分讲了主角&#xff0c;作为…

Delphi编程:pagecontrol组件的tab字体变大

1、将pagecontrol组件属性中的font的字体变成四号。 2、将tabsheet1属性中的font的字体设置成八号。 结果如下&#xff1a;

水果种植与果园监管“智慧化”,AI技术打造智慧果园视频综合解决方案

一、方案背景 我国是水果生产大国&#xff0c;果园种植面积大、产量高。由于果园的位置大都相对偏远、面积较大&#xff0c;值守的工作人员无法顾及到园区每个角落&#xff0c;因此人为偷盗、野生生物偷吃等事件时有发生&#xff0c;并且受极端天气如狂风、雷暴、骤雨等影响&a…