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

news2025/1/12 19:51:03

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
{
    @Id
    private Integer id; //即使这里类型是Integer,可是存到redis后,也会变成String类型

    //Indexed 指定对普通类型的属性建立索引,索引化后的属性才可用于查询。
    @Indexed
    private String name;
    @Indexed
    private 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对象的方法
    @Override
    public void hmset(String key, Map<String, String> value)
    {
        //调用 HashOperations 的方法来向数据库中存入 Hash 对象
        //要操作的value的类型是hash对象,就用.opsForHash() 方法
        stringRedisTemplate.opsForHash().putAll(key, value);
    }


    //自定义查询价格高于某个点的Book对象
    @Override
    public List<Book> findByPriceGt(double startPrice)
    {
        //由于 price 没有用注解@Indexed 建立索引,因此不能直接根据price来查询
        //首先获取全部的Book对象,redis会自动把我们添加的所有Book对象中的id,都存在一个set集合里面,因此先把id从set集合中都拿出来
        //要操作的value的类型是 set 集合,就用.opsForSet() 方法,此处的 books 就是 Book对象上 @RedisHash("books") 所指定的key
        Set<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获取所有的实体对象Book
        for (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


    //=========================================样本查询=========================================

    @Autowired
    private BookDao bookDao;


    //==========================自定义查询================================

    //自定义添加hash对象的方法
    @Test
    public 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.coloradmin.cn/o/1065648.html

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

相关文章

微信小程序wxs标签 在wxml文件中编写JavaScript逻辑

PC端开发 可以在界面中编写JavaScript脚本 vue/react这些框架更是形成了一种常态 因为模板引擎和jsx语法本身就都是在js中的 我们小程序中其实也有类似的奇妙写法 不过先声明 这东西不是很强大 我们可以先写一个案例代码 wxml代码参考 <view><wxs module"wordSt…

如何与瑞诺司Rhenus 建立EDI连接?

Rhenus Automotive 是德国百年家族企业Rethmann Group的子公司&#xff0c;提供从零部件的有序供应、即装即用模块的组装&#xff0c;一直到整车的组装。主要在全球范围内为劳斯莱斯&#xff0c;宝马&#xff0c;奔驰&#xff0c;奥迪等汽车企业提供智能制造解决方案。 项目挑战…

阿拉伯文排版是如何实现的

背景&#xff1a; 今天开工了&#xff0c;无意间看到多语言的页面&#xff0c;毕竟我们网站也是有多语言的 但是并没有阿拉伯语。但是我很好奇&#xff0c;分析阿拉伯语言的css并没有发现什么猫腻&#xff01; 到底是怎么实现的呢&#xff1f; 解&#xff1a; html dir 属性 …

聊聊MySQL的聚簇索引和非聚簇索引

文章目录 1. 索引的分类1. 存储结构维度2. 功能维度3. 列数维度4. 存储方式维度5. 更新方式维度 2. 聚簇索引2.1 什么是聚簇索引2.2 聚簇索引的工作原理 3. 非聚簇索引&#xff08;MySQL官方文档称为Secondary Indexes&#xff09;3.1 什么是非聚簇索引3.2 非聚簇索引的工作原理…

win7怎么录屏视频?小白也能轻松学会

“win7怎么录屏视频呀&#xff1f;在学校机房上课&#xff0c;电脑都是win7系统的&#xff0c;每次需要录屏的时候都找不到方法&#xff0c;问了老师也解决不了&#xff0c;有人知道win7怎么录屏吗&#xff1f;” Windows 7系统已经逐渐淡出了主流操作系统的行列&#xff0c;但…

JVM上篇之虚拟机与java虚拟机介绍

目录 虚拟机 java虚拟机 简介 特点 作用 位置 整体结构 类装载子系统 运行时数据区 java执行引擎 Java代码执行流程 jvm架构模型 基于栈式架构 基于寄存器架构 总结 jvm的生命周期 1.启动 2.执行 3.退出 JVM的发展历程 虚拟机 所谓虚拟机&#xff0c;指的…

要体验 AI 编程助手吗?

能不能用 AI 编程辅助写代码&#xff1f; 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点&#xff0c;和项目&#xff0c;并将中国优秀开发者或技术…

强化学习实践(二)Gym(安装、环境搭建、运行倒立摆(代码可运行))

1.准备工作 优先选用conda&#xff0c;conda不仅可以安装python&#xff0c;也是环境管理的工具&#xff0c;我们可以通过conda创建python环境&#xff0c;每个环境之间是相互独立&#xff0c;这样不同的环境可以使用不同版本的python&#xff0c;不同版本的开发包&#xff0c;…

UEditorPlus v3.5.0 支持音频组件,字体图标请求合并,服务器配置优化

UEditor是由百度开发的所见即所得的开源富文本编辑器&#xff0c;基于MIT开源协议&#xff0c;该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器&#xff0c;主要做了样式的定制&#xff0c;更符…

栈溢出至getshell分析及利用

公众号&#xff1a;掌控安全EDU 分享更多技术文章&#xff0c;欢迎关注一起探讨学习 Ret2text&#xff08;源程序中存在system及/bin/sh&#xff09; 控制程序执行程序本身已有的的代码(.text)。栈溢出&#xff0c;存在system()函数以及”/bin/sh”字符串。通过溢出将返回地址…

LeetCode算法心得——有序三元组中的最大值 II (简单的动规思想)

大家好&#xff0c;我是晴天学长&#xff0c;枚举&#xff0b;简单的动态规划思想&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。 1) .有序三元组中的最大值 II 有序三元组中的最大值 II 给你一个下标从 0 开始的整数数组 nums 。 请你从所有满足 …

STM32F4X UCOSIII 互斥量

STM32F4X UCOSIII 互斥量 互斥量的概念互斥量的工作机制洗手间问题互斥量优先级继承没有优先级继承优先级继承 UCOSIII互斥量API互斥量创建函数互斥量删除函数互斥量申请函数互斥量释放函数 UCOSIII 互斥量例程 互斥量的概念 UCOSIII中的互斥量是一种特殊的信号量&#xff0c;…

重磅!这本SSCI期刊已解除On Hold状态!警惕目前6本SCIE/ESCI期刊被标记!

期刊动态&#xff1a;新增一本SSCI解除“On Hold” 最新消息&#xff0c;SSCI期刊Transformations in Business & Economics在之前被标记为On Hold&#xff0c;目前该标识已取消&#xff01;表示目前该期刊被SSCI数据库正常收录检索。 往期期刊On Hold情况&#xff1a; …

云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

递归解析Json,实现生成可视化Tree+快速获取JsonPath | 京东云技术团队

内部平台的一个小功能点的实现过程&#xff0c;分享给大家&#xff1a; 递归解析Json&#xff0c;可以实现生成可视化Tree快速获取JsonPath。 步骤&#xff1a; 1.利用JsonPath读取根&#xff0c;获取JsonObject 2.递归层次遍历JsonObjec&#xff0c;保存结点信息 3.利用z…

钡铼BL124EC实现EtherCAT转Ethernet/IP的优势

钡铼技术的BL124EC是一款用于将EtherCAT从站转换为Ethernet/IP从站的网关设备。它是钡铼技术开发的高性能、可靠的工业自动化通信解决方案之一。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; BL124EC网关可以应用于多种工业自动化场景&#xff0c;以下…

1.6 IntelliJ IDEA开发工具

前言&#xff1a; ### 1.6 IntelliJ IDEA开发工具笔记 - **背景**&#xff1a; - 使用基础文本编辑器如记事本编写Java代码虽然可行&#xff0c;但存在效率低下且难以调试的问题。 - 集成开发环境 (IDE) 可以有效地提高Java程序的开发效率。 - **常见Java IDE**&#xf…

解决docker开启MySQL的binlog无法成功。docker内部报错:mysql: [ERROR] unknown variable

1. 报错信息 2. 操作流程 整个流程是这样的&#xff1a; 我愉快的输入docker ps&#xff0c;查看MySQL的docker 容器id 执行指令docker exec -it 8a \bin\bash进入容器内部执行vim /etc/my.cnf&#xff0c;打开配置文件按照网上说的&#xff0c;添加如下配置信息退出docker容…

韦东山老师 RTOS 入门课程(二)理解任务的创建,切换过程

RTOS 的核心实现&#xff1a;保存&#xff0c;恢复现场 接下来开始尝试实现 RTOS。当然我们开发的时候其实不用这样做&#xff0c;现在尝试实现只是为了更好地理解原理。 RTOS 的核心就是刚才在研究的问题&#xff1a;保存和恢复现场。再追其本质&#xff0c;其实就是所有寄存…

【Linux】 文件类型和访问权限

执行 ls -l &#xff08;或者&#xff1a;ll &#xff09; 指令查看文件的具体属性。 示例&#xff1a; drwxr-xr-x. 2 root root 33 10月 7 11:27 test2 看图说话&#xff1a; 下面是示例分解图 第一列的字符表示文件或目录的类型和权限。 第一个字符表示文件类型 例如&…