Redis的安装(linux、docker)与其基本的api使用

一、Redis简介

  1. Redis是一个开源的,使用 C 编写,高性能的Key-Value的NoSQL数据库。
    • SQL :关系型数据库,例如:MySQL,Oracle等等
    • NoSQL :Not Only SQL 不仅仅是SQL,表示是非关系型数据库

Redis特点

  1. 基于内存
  2. 可持久化数据
  3. 具有丰富的数据结构类型,适应非关系型数据的存储需求
  4. 支持绝大多数主流开发语言,如C、C++、Java、Python、R、JavaScript等。
  5. 支持集群模式,高效、稳定。

Redis的数据模型

  1. 键值对形式。(key:value模型)
  2. Redis的数据结构类型,指的就是Redis值的结构类型(即value的数据类型)。

在这里插入图片描述

Redis作用

  1. 本质是数据库,能存储数据。
  2. Redis能灵活处理非关系型数据的读、写问题,是对MySQL等关系型数据库的补充。
    • 新浪微博就是使用Redis集群做数据库。
    • 应用场景:微博、即时通讯、验证码,单点登录,缓存等
  3. . 缓存数据。
    • 所谓缓存,就是将数据加载到内存中后直接使用,而不是每次都通过IO流从磁盘上读取。而Redis则是将数据直接存储在内存中,只有当内存空间不足时,将部分数据持久化到磁盘上。

      • 好处:读写效率高。

二、Redis安装

  • 因为Redis官方只提供了源码,并没有提供经过编译之后的安装包,直接在Linux安装相对繁琐复杂。
    • 所以使用docker安装(前提需要熟悉docker)

第1步、下载redis的docker镜像

docker pull redis:6.2.13

在这里插入图片描述

第2步、 创建并启动容器

  • 创建本地映射目录
mkdir -p /usr/local/docker/redis/config
mkdir -p /usr/local/docker/redis/data
  • 并把redis.conf配置文件上传到 /usr/local/docker/redis/config目录(使用客户端软件Xsheel,xftp,MobaXterm等把redis.conf配置文件上传到该目录下)
    在这里插入图片描述

在这里插入图片描述

第3步、 使用docker命令启动名称创建容器

docker run --restart=always \
-p 6379:6379 \
--name redis \
-v /usr/local/docker/redis/config/:/etc/redis/ \
-v /usr/local/docker/redis/data:/data \
-d redis:6.2.13 redis-server /etc/redis/redis.conf

在这里插入图片描述

命令解释

docker run               创建并运行

--restart=always        运行容器随Linux开机启动

-p 6379:6379               端口映射 -》 -p 宿主机对外暴露端口:容器端口

--name redis         指定容器名称
-v /usr/local/docker/redis/config/:/etc/redis/            把redis容器的/etc/redis/目录  到宿主机的 /usr/local/docker/redis/config/(映射配置文件)
-v /usr/local/docker/redis/data:/data                     映射redis持久化数据目录

-d redis:6.2.13 redis-server /etc/redis/redis.conf
	-d             进程在后台启动的模式
	redis:6.2.13        是redis镜像版本
	redis-server /etc/redis/redis.conf 			redis容器中的服务指定读取的配置文件位置

第4步、查看容器

使用docker ps 指令查看运行的容器
如果看到redis,说明redis安装成功
在这里插入图片描述

到这里就说明安装成功了

第5步、进入容器

docker exec -it redis bash

在这里插入图片描述

第6步、登录redis

  • 因为默认没有设置密码,所以进去无需登录,直接就可以使用

  • 启动redis客户端,登录 /usr/local/bin/redis-cli

在这里插入图片描述

redis.conf常用配置说明

修改了配置文件之后,需要重新启动redis服务

docker restart redis

1、requirepass foobar(需要自己操作的)

(vim进入命令模式,输入/然后加上想要查找的关键词,回车进行搜索,按n进行查找下一个)
给redis设置密码(配置文件里面默认是没有配置的)
在这里插入图片描述

  • 修改配置文件后,需要重新启动redis
    在这里插入图片描述

2、databases 16 (不需要自己操作的)

Redis默认有16个数据库,寻址下标从0开始。
默认连接db0
在这里插入图片描述

3、 port 6379(不需要自己操作的)

指定redis的服务端口,默认6379.
在这里插入图片描述

4、配置redis的bind(需要自己操作的)

只有操作了此步骤外界才能访问当前redis

  • Redis默认只能当前主机访问127.0.0.1需要修改配置其他机器才能访问
    在这里插入图片描述
    在这里插入图片描述

5、dbfilename dump.rdb、dir ./(不需要自己操作的)

  • 指定数据持久化的文件名及目录。
  • docker创建默认的数据持久化目录在/data 目录
    在这里插入图片描述

使用客户端访问

  • 在windows上安装访问客户端(傻瓜式安装)
    https://github.com/qishibo/AnotherRedisDesktopManager/releases

    在这里插入图片描述
  • 连接:填入对应的redis所在的ip地址,还有端口号,以及密码,即可连接成功。
    在这里插入图片描述
    在这里插入图片描述

三、Redis的使用

Redis的键key与值value(数据结构类型)

  1. Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型。
    • Redis的数据结构类型,指的就是redis的值value的类型;
    • Redis常用的数据结构类型:string、list、set、sortedSet、hash
      • 字符串 string:普通字符串,Redis中最简单的数据类型(常用)
      • 哈希 hash:也叫散列,类似于Java中的HashMap结构(一般拿来存储对象)
      • 列表 list:按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList
      • 集合 set:无序集合,没有重复元素,类似于Java中的HashSet
      • 有序集合 (sorted set / zset):集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素

1、Redis的键key

  1. key的类型:redis的key 值是二进制储存的,这意味着可以用任何二进制序列作为key值,从形如”foo”的简单字符串到一个JPEG文件的内容都可以。

    • 空字符串也是有效key值。
    • redis建议使用字符串做为key的类型
  2. key取值规范

      1. 键值不需要太长,消耗内存,在数据中查找这类键值的计算成本较高
      1. 键值不宜过短,可读性较差,通常建议见名知意
  3. key的取值举例:
    在这里插入图片描述

set user:id:1:username lisi

# set user:id:1:username lisi命令可以理解为将一个用户的用户名设置为lisi,
# 其中set是Redis提供的设置命令,user:id:1:username是键(key),
# lisi是该键对应的值(value)。这个命令实际上是将用户ID为1的用户的用户名设置为lisi。
# 在Redis中,键值对的设计非常灵活,可以根据实际情况进行设置。

set user:id:1:password 111111

set user:id:1:email lisi@163.com

在这里插入图片描述

key命令

在这里插入图片描述

  • exists key :检查给定key是否存在。(1表示存在,0表示不存在)

    • 注意事项,不支持通配符
      在这里插入图片描述
  • del key :删除一个key
    在这里插入图片描述

  • del key1 key2 key3:删除多个key
    在这里插入图片描述

  • keys pattern (模糊查找):查找所有符合给定模式 pattern 的 key 。

    • keys * :匹配数据库中所有 key 。
    • keys n?me: 匹配 name、neme、nfme 等。
    • keys n* :匹配 name、neme、naaaaame等。
    • keys n[ae]me :只能匹配 name、neme。

在这里插入图片描述

  • expire key seconds:指定key的过期时间。

    • 新添加的key,如果没有指定过期时间,则会一直保存。
    • 可以对一个已经带有生存时间的key执行EXPIRE命令,新指定的生存时间会取代旧的生存时间。
  • ttl key:查看某个key的剩余过期时间,返回值:

    • -2 表示这个key已经过期,删除掉
    • -1 表示没有设置过期时间
    • 其它表示剩余的生存时间,单位为秒。
      在这里插入图片描述
  • rename

    • 语法格式:rename key newkey,表示将 key 改名为 newkey 。
    • 当 key 不存在时,返回一个错误。
    • 当 newkey 已经存在时, RENAME 命令将覆盖旧值。
      在这里插入图片描述
  • type key :查看key对应的value的数据结构类型。
    在这里插入图片描述

  • get key :查看某一个key的值
    在这里插入图片描述

其它key命令见redis帮助文档 http://doc.redisfans.com/

2、Redis的值Value

String类型
  1. string类型是redis最常用的数据结构类型,存储的值为字符串
    在这里插入图片描述
    String相关命令
  • set key value :设置一个key,值为value,类型为String类型;

    • 如果这个key已经存在,则更新这个key的值。返回oK成功
      在这里插入图片描述
  • setnx key value : 如果这个key不存在,则设置一个key,值为value;

    • 如果key存在,则不做更新。
    • 返回值
      • 1 表示成功
      • 0 表示失败
        在这里插入图片描述
  • get key: 获取key对应的value值;

    • 如果key不存在,则返回nil
      在这里插入图片描述
  • mget key1 key2 key3 :一次获取多个key的值,如果对应key不存在,则对应返回nil
    在这里插入图片描述

  • incr key : 将key 中储存的数字值增一,然后返回。

    • 如果这个key不存在,那么key的值会先被初始化为0,然后再执行INCR操作。
    • 如果这个key对应的value值,不能表示数字,则会返回一个错误。
      在这里插入图片描述
  • incrby key increment :将key增加指定的步长值。

    • increment是步长
      在这里插入图片描述
  • decr key (decrement):将key 中储存的数字值减一,然后返回。

    • 如果这个key不存在,那么key的值会先被初始化为0,然后再执行DECR操作。
    • 如果这个key对应的value值,不能表示数字,则会返回一个错误。
      在这里插入图片描述
  • decrby key decrement :将key减少对应的步长值。
    在这里插入图片描述

  • append key value :如果key已经存在,则将value追加到这个key原先的value值的末尾。如果这个key不存在,则执行set操作。

在这里插入图片描述

String类型的应用场景
  1. 做与统计有关的业务,如新浪微博(微信朋友圈)中的点赞功能
  2. 购物车的商品添加数量的功能(+,-键的功能)
解决多线程的线程安全问题
  • Redis6.0以前的key是单线程模式,这就意味一瞬间只有一个线程能够持有这个key,所以可以使用redis解决部分涉及线程安全的业务。
    • 比如,在初级时候通过多线程模拟卖票,使用加锁的方式,保证只有一个线程能够持有锁,进行买票业务。还有点赞功能基本上都是使用redis技术实现的。redis6.0版本前是单线程的,6.0之后是支持多线程的,默认多线程是关闭的
List类型
  1. value类型是List的特点:

    • 基于Linked List实现
    • 元素是字符串类型
    • 列表头尾增删快,中间增删慢,增删元素是常态
    • 元素可以重复出现
    • 最多包含(2^32)-1元素
  2. 列表的索引

    • n 从左至右,从0开始
    • n 从右至左,从-1开始

在这里插入图片描述

在这里插入图片描述
list相关命令

  • lpush key value [value …] :将一个或多个值value插入到列表key的表头(即从左边插入);

    • 如果有多个value值,那么各个value值按从左到右的顺序依次插入到表头:比如说,对空列表mylist执行命令LPUSH mylist a b c,列表的值将是 c b a 这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令;
    • 如果key 不存在,一个空列表会被创建并执行 LPUSH 操作。
    • 当key 存在但不是列表类型时,返回一个错误。
      在这里插入图片描述
  • rpush key value [value …] :尾部添加(从右向左),操作同上。
    在这里插入图片描述

  • llen key :返回key对应list的长度;

    • key不存在返回0
    • 如果key对应类型不是list返回错误
      在这里插入图片描述
  • lindex key index :index元素在list列表中的下角标,从0开始;

    • lindex 是从左到右取元素
      在这里插入图片描述
  • lrange key start stop :获取指定区间的所有元素;

    • 下角标从0开始,0表示第一个元素,1表示第二个,依次类推;
    • -1表示最后一个元素,-2表示倒数第二个元素,依次类推;
      在这里插入图片描述
  • lpop key :移除并返回列表中的第一个元素

  • rpop key :移除并返回列表中的最后一个元素。

在这里插入图片描述

List类型应用场景
  1. 处理排名类业务。如新浪微博评论、论坛回帖楼层等。
  2. 聊天室
Hash(散列)类型
  • hash数据类型 是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象
    在这里插入图片描述
  1. hash类型的特点:
      1. 由Field和与之关联的value组成map键值对
      1. field和value是字符串类型;
      1. 一个hash中最多包含2^32-1键值对。

在这里插入图片描述
hash相关命令

  • hset key field value :设置hash field为指定值;

    • 如果key不存在,则先创建;
    • 如果field已经存在,那么将更新这个field的值。
  • hget key field :获取指定的hash field
    在这里插入图片描述

  • hmget key filed1…fieldN :获取全部指定的hash的key对应的 filed
    在这里插入图片描述

  • hmset key filed1 value1 … filedN valueN :同时设置hash的多个field

  • hkeys key :返回hash对应的key的的所有field

  • hvals key 返回hash对应的key的所有value
    在这里插入图片描述

  • hexists key field :判断指定的key对应的field是否存在
    在这里插入图片描述

  • hdel key field :删除指定的hash指定的key对应的 field

  • hlen key :返回指定hash的field数量

在这里插入图片描述

  • hgetall key 返回hash的所有filed和value
    在这里插入图片描述
Hash的用途(能使用hash的时候尽量使用hash)
  1. 节约内存空间:
    • redis每创建一个键(key),都会为这个键储存一些附加的管理信息(比如这个键的类型,这个键最后一次被访问的时间等等)
    • redis的key相对于值来说,更珍贵!!!
      • 所以数据库里面的键越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,在获取key对应的value值时cpu的开销也会更多
    • Hash结构可以将具有关联关系的一组key-value,存储到同一个hash结构中,从而减少key的数量。
hash不适用的场景
  • 如果我们仅仅只对一个字段设置过期,就不建议使用hash。
  • Redis的key的过期功能只能对键操作,而Hash结构不能单独对某一个filed设置过期功能。

说明:在实际开发中,能使用hash的时候,尽量使用hash!!

Set类型(集合)

在这里插入图片描述

  1. redis的value的数据类型为set的特点:
      1. 无序的、去重的;
      1. 元素是字符串类型;
      1. 最多包含(2^32)-1元素

在这里插入图片描述
set相关命令

  • sadd key member [member …](member要无序不重复) :

    • 将一个或多个member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
    • 假如key 不存在,则创建一个只包含 member 元素作成员的集合。
    • 当key 不是集合类型时,则返回一个错误。
      在这里插入图片描述
  • smembers key :

    • 返回集合key 中的所有成员。
    • 不存在的key 被视为空集合。
    • 不是set类型的key会报错
      在这里插入图片描述
  • spop key :移除并返回集合中的一个随机元素。

    • 被移除元素是随机的。
    • 当key不存在或key是空集时,返回nil。
      在这里插入图片描述
  • scard key :

    • 返回集合key的基数(集合中元素的数量)。
    • 当key不存在时,返回0。
      在这里插入图片描述
  • sinter key [key …] :

    • key只有一个时返回一个集合的全部成员
    • key有多个时,返回的是所有key集合的交集。
    • 不存在的key 被视为空集。
      在这里插入图片描述
  • sunion key [key …] :

    • 如果只有一个key时,返回一个集合的全部成员
    • 如果有多个key时,饭返回所有key集合的并集。
    • 不存在的key 被视为空集。
      在这里插入图片描述
  • sdiff key [key …] :

    • key只有一个时,返回一个key集合的全部成员
    • key有多个时,返回所有key集合之间的差集。
    • 不存在的key 被视为空集。

在这里插入图片描述

set数据类型应用场景
  1. 新浪微博的共同关注
  • 需求:当用户访问另一个用户的时候,会显示出两个用户共同关注哪些相同的用户

  • 设计:将每个用户关注的用户放在集合中,求交集即可

  • 实现如下:

peter={'john','jack','may'}
ben={'john','jack','tom'}

那么peter和ben的共同关注为:
SINTER peter ben 结果为{'john','jack'}

SortedSet类型

在这里插入图片描述

  1. Redis的value的数据类型SortedSet数据类型的特点:
      1. 类似Set集合;
      1. 有序的、去重的;
      1. 元素是字符串类型;
      1. 每一个元素都关联着一个浮点数分值(Score),并按照分值从小到大的顺序排列集合中的元素。分值可以相同
      1. 最多包含2^32-1元素

在这里插入图片描述

  • zadd key [sort member sort member] : 向有序集合添加一个或多个成员

    • 如:zadd set1 1 zhangsan 2 lisi
  • zrange key start end [withscores] :查询指定范围的值升序排序

    • 如:zrange set1 0 10
    • Start 索引 从0开始 stop 结束索引或者-1(最后一个)
      在这里插入图片描述
  • zrevrange ket start end [withscores]: 查询指定范围的值降序排序

    • 如:zrange set1 0 10
    • Start 索引 从0开始 stop 结束索引或者-1(最后一个)
      在这里插入图片描述
  • zcount key start end :统计一个范围内元素的个数

    • 如:zcount set1 0 10
    • 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
      在这里插入图片描述
  • zcard key: 统计元素的个数

    • 如:zcard set1
      在这里插入图片描述
  • zrank key 返回成员的索引号

    • 如:zrank set1 lucy
      在这里插入图片描述
  • zrem key member1 […membern] 删除成员

    • 如:zrem set1 zhangsan
      在这里插入图片描述
sortedSet数据类型的适用场景

适用于需要有序且唯一的业务或操作:

  1. 网易音乐排行榜
    • 分析:
      • 每首歌的歌名作为元素(唯一、不重复)
      • 每首歌的播放次数作为分值
      • ZREVRANGE来获取播放次数最多的歌曲(就是最多播放榜了,云音乐热歌榜,没有竞价,没有权重)

四、在java中操作redis

第一步:创建springboot项目:

在这里插入图片描述

  • 选择redis依赖
    在这里插入图片描述

第二步:进行redis相关配置

# redis??
spring:
  data:
    redis:
      host: 192.168.70.130 #虚拟机地址
      port: 6379 #  端口号
      password: 123456 # 密码
      connect-timeout: 60000 # 
      lettuce:
        pool: #?????
          max-active: 512 #?????
          max-idle: 128 #???????
          min-idle: 128 #???????
          max-wait: 1000ms #????????

第三步:写测试类(StringRedisTemplate测试类):

  • StringRedisTemplate测试类:
    • StringRedisTemplate操作的都是字符串类型的数据
package com.knife;

import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;

import java.time.Duration;
import java.util.*;

@SpringBootTest
class RedisDemoApplicationTests {

	@Resource
	private StringRedisTemplate stringRedisTemplate;

	/**
	 * String类型操作
	 */
	@Test
	void testString() {
		//获取操作String类型的对象
		ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();

		//设值
		opsForValue.set("name", "zhangsan");
		opsForValue.set("age", "18");

		//获取值
		String name = opsForValue.get("name");
		System.out.println("name = " + name);

		//递增
		opsForValue.increment("star");

		//递减
		opsForValue.increment("star");

		//设值key超时自动清除1s超时(一般用并发简单的分布式锁)
		opsForValue.set("temp", "suiyi", Duration.ofSeconds(1));

		//删除
//		stringRedisTemplate.delete("age");
//		stringRedisTemplate.delete("name");
	}

	/**
	 * List类型操作
	 */
	@Test
	void testList() {
		ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();
		//添加单个值(左)
		opsForList.leftPush("names", "张三");
		//添加单个值(右)
		opsForList.rightPush("names", "李四");

		//添加多个值(右)
		//添加多个值(左)
		opsForList.leftPushAll("names", "小明", "小红", "小芳");
		//添加多个值(右)
		opsForList.rightPushAll("names", "tom", "jerry", "ben");

		//获取值(获取所有)
		List<String> names = opsForList.range("names", 0, -1);
		System.out.println("names = " + names);

		//删除(从左)
		String name = opsForList.leftPop("names");
		System.out.println("name = " + name);
		//删除(从右)
		name = opsForList.rightPop("names");
	}

	/**
	 * Hash类型操作
	 */
	@Test
	void testHash() {
		//获取hash对象
		HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();

		//设置hash以及字段值
		opsForHash.put("user:id:1", "name", "张三");
		opsForHash.put("user:id:1", "age", "18");
		opsForHash.put("user:id:1", "sid", "202108764226");
		opsForHash.put("user:id:1", "gender", "男");
		opsForHash.put("user:id:1", "phone", "19876850907");

		//添加map
		HashMap<String, Object> userMap = new HashMap<>();
		userMap.put("name", "小敬哥");
		userMap.put("age", "29");
		userMap.put("gender", "男");
		userMap.put("sid", "202108764226");
		opsForHash.putAll("user:id:2", userMap);


//		查询key的所有数据
		Map<Object, Object> entries = opsForHash.entries("user:id:1");
		System.out.println(entries);

		//删除指定的1-n个field(字段)
		opsForHash.delete("user:id:2", "age", "gender");

		//获取单个field值
		String name = (String) opsForHash.get("user:id:1", "name");

//		获取所有字段
		List<Object> values = opsForHash.values("user:id:1");
		System.out.println(values);

		//获取多个field值
		List<Object> fields = Arrays.asList("name", "age", "gender");
		List<Object> objects = opsForHash.multiGet("user:id:1", fields);
		System.out.println("objects = " + objects);
	}

	/**
	 * Set类型操作
	 */
	@Test
	void testSet() {
		//获取操作Set对象
		SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();

		//添加元素
		opsForSet.add("language1","java","php","c");
		opsForSet.add("language2","java","go","c++");
		opsForSet.add("girls", "西施", "貂蝉", "王昭君", "杨玉环", "凤姐");

//		随机删除一个字段并返回字段
		String language1 = opsForSet.pop("language1");
		System.out.println(language1);


		//获取所有元素
		Set<String> girls = opsForSet.members("girls");
		System.out.println("girls = " + girls);

		//删除指定的元素
		opsForSet.remove("girls", "凤姐", "杨玉环");

//		取两个集合的交集
		Set<String> intersect = opsForSet.intersect("language1", "language2");
		System.out.println("intersect="+ intersect);

//		取两个集合的全集
		Set<String> union = opsForSet.union("language1", "girls");
		System.out.println("union =" + union);


	}

	/**
	 * SortedSet操作
	 */
	@Test
	void testSortedSet() {
		//获取SortedSet对象
		ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
		//添加元素
		opsForZSet.add("fruits", "西瓜", 1.0);
		opsForZSet.add("fruits", "苹果", 2.0);
		opsForZSet.add("fruits", "梨", 3.0);
		opsForZSet.add("fruits", "火龙果", 4.0);
		opsForZSet.add("fruits", "葡萄", 3.5);

		//获取所有元素(按分值低到高)
//		从0开始取,取到末尾,-1表示末尾的元素
		Set<String> fruits = opsForZSet.range("fruits", 0, -1);
		System.out.println("fruits = " + fruits);

		//获取所有元素(按分值高到低)
		fruits = opsForZSet.reverseRange("fruits", 0, -1);
		System.out.println("fruits = " + fruits);

		//获取分值范围的元素
		Long count = opsForZSet.count("fruits", 1.0, 2.0);
		System.out.println("count = " + count);

//		按照分值范围获取数据
		Set<String> fruits1 = opsForZSet.rangeByScore("fruits", 3.0, 5.0);
		System.out.println(fruits1);

		//删除
		opsForZSet.remove("fruits","西瓜","火龙果");
		System.out.println(opsForZSet.reverseRange("fruits", 0, -1));
	}
}

第三步:写测试类(RedisTemplate测试类):

  • RedisTemplate测试类:
    • RedisTemplate可以存储对象

在上面创建项目的基础上添加下面的依赖:

<!-- lombok的依赖-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

<!-- 针对RedisConfig的依赖-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
  • pojo类需要实现序列化接口,因为redis存储对象时候实际上是将对象进行序列化数据后存储到Redis
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private Integer id;
    private String name;
    private Integer age;
    private String phone;
}

测试类:

package com.knife;

import com.knife.pojo.User;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
public class RedisTemplateTest {

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Test
    void test1(){
        ValueOperations<String, Object> vos = redisTemplate.opsForValue();
        User user = new User(1,"zhangsan",11,"12349023910");
//        要把对象存入redis,需要把该类实现Serializable,这样才可以序列号
        vos.set("user",user);
        Object o = vos.get("user");

        System.out.println(o);
    }

}

在这里插入图片描述

  • RedisTemplate可以直接将我们的程序的Java对象存储到Redis中,不过·默认会将非字母和数字的其他数据转换成hex16进制·,虽然不影响程序运行,但是不太方便开发者进行开发阅读。

配置RedisTemplate序列化器

  1. 一般都是将Java对象序列化为json,也可以直接将Redis中数据获取出来直接反序列化成Java对象
    • 这里需要配置RedisTempate将数据存储到Redis的时候序列化为JSON字符串选用的序列化器
      • json序列化我们可以使用SpringMVC官方推荐的jackson或者是alibba的fastjson

创建RedisConfig配置类

package com.knife.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    /**
     * RedisTemplate配置
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 配置redisTemplate
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

//        这里爆红是因为过时了,但是还能用
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // key序列化(使用redis自身的序列化)
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // value序列化(使用springboot自带的json序列化)
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

        // Hash key序列化(使用redis自身的序列化)
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // Hash value序列化(使用springboot自带的json序列化)
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

继续使用上面的测试类进行测试;

  • RedisTemplate使用序列化器以后存储的效果就是一个json字符串,实际开发也推荐使用此种方式。
    在这里插入图片描述

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

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

相关文章

java之mybatis笔记

1 项目创建 1.1 maven设置 1.2 创建项目文件 1.3 配置MyBatis的相关依赖 1.4 配置 MyBatis 创建一个 mybatis-config.xml 配置文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org…

【java】指定类,指定package,找到package下面,这个类的所有子类

目录 ■java代码 ■注意 ■运行效果 ■包的结构 ■java代码 package com.sxz.study.reflect;import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List;public class …

观察者模式(大话设计模式)C/C++版本

观察者模式 扩展&#xff1a;观察者模式——委托 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15905936.html #include <iostream> #include <list> #include <memory> #include <string> using namespace std;// Observer类 抽象观…

【Spine学习09】之导入皮肤两种方式[skin]

第一种&#xff1a;明确项目中某个角色是有两套皮肤的情况下 直接导入两套皮肤 1、添加SKIN皮肤指令 2、在ps中-文件-脚本-浏览【打开选中jsx脚本】 3、打开Spine 点击左上角&#xff0c;选择导入数据 就可以看到该角色的两套皮肤啦&#xff01; 第二种&#xff1a;刚开始角…

探索档案未来,尽在ARCHE-2024

2024年第三届上海国际智慧档案展览会暨高峰论坛&#xff08;ARCHE-2024&#xff09;将于2024年6月19日至21日在上海跨国采购会展中心隆重举行。深圳市铨顺宏科技有限公司应邀参展&#xff0c;将以全新形象盛装亮相&#xff0c;展示其在档案管理领域的最新技术和解决方案。 ARC…

2024年【N2观光车和观光列车司机】考试技巧及N2观光车和观光列车司机模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 N2观光车和观光列车司机考试技巧参考答案及N2观光车和观光列车司机考试试题解析是安全生产模拟考试一点通题库老师及N2观光车和观光列车司机操作证已考过的学员汇总&#xff0c;相对有效帮助N2观光车和观光列车司机模…

网络安全形势迫在眉睫!云WAF保护私有云安全!

业务上云面临新的WEB安全挑战 目前&#xff0c;所有的组织都在积极地接受企业的“云”&#xff0c;推进数字化变革。在服务云计算和私有云平台构建中&#xff0c;用户除了要面对各种常见的网络攻击&#xff0c;还需要面对虚拟环境下的非授权访问、虚拟机逃逸和敏感信息泄漏等问…

【Mongodb-01】Mongodb亿级数据性能测试和压测

mongodb数据性能测试 一&#xff0c;mongodb数据性能测试1&#xff0c;mongodb数据库创建和索引设置2&#xff0c;线程池批量方式插入数据3&#xff0c;一千万数据性能测试4&#xff0c;两千万数据性能测试5&#xff0c;五千万数据性能测试6&#xff0c;一亿条数据性能测试7&am…

Java新特性与性能调优

引言 Java不断演进&#xff0c;每个新版本都引入了新的特性和改进&#xff0c;帮助开发者在提高生产力的同时&#xff0c;也能更好地优化程序性能。本文将详细介绍Java新版本中的重要特性&#xff0c;如从Java 8到Java 17&#xff0c;并探讨性能调优的方法&#xff0c;包括JVM调…

Python自动化办公(二) —— 查看文件夹中的PDF文件数量

Python自动化办公&#xff08;二&#xff09; —— 查看文件夹中的PDF文件数量 在日常办公中&#xff0c;我们经常需要统计某个文件夹中的PDF文件数量。手动操作不仅费时费力&#xff0c;而且容易出错。幸运的是&#xff0c;使用Python可以轻松实现这个过程。本文将介绍如何使用…

【字符串函数2】

5. strncpy 函数的使用和模拟实现 选择性拷贝 char * strncpy ( char * destination, const char * source, size_t num ); 1.拷贝num个字符从源字符串到目标空间。 2.如果源字符串的⻓度⼩于num&#xff0c;则拷⻉完源字符串之后&#xff0c;在⽬标的后边 追加0 &#…

MyBatis-Plus整合达梦数据库

文章目录 1. 环境准备2. 创建Spring Boot项目3. 引入依赖4. 配置数据源5. 配置MyBatis-Plus6. 创建实体类7. 创建Mapper接口8. 创建Service类9. 创建Controller类10. 创建Mapper XML文件11. 测试12. 进一步优化12.1 配置分页插件12.2 配置乐观锁插件13. 总结🎉欢迎来到Java学…

案例学习-存量更新规划实施探索(武汉)

案例学习-存量更新规划实施探索&#xff08;武汉&#xff09; 武汉市在早期旧城更新实践中发现零散化的更新往往导致资源配置分散、城市建设破碎化等弊病&#xff0c;特别是由于过于强调项目自身“经济平衡”&#xff0c;在实施过程中也逐步暴露出住宅占比过大、强度偏高、公服…

屹晶微EG3002 单通道功率MOSFET驱动芯片 贴片SOP8

EG3002作为一款功率MOSFET驱动芯片&#xff0c;它的应用领域主要取决于其技术参数和性能特点。根据之前提供的信息&#xff0c;EG3002可能适用于以下领域&#xff1a; 1. 电源管理&#xff1a;用于高效率电源转换器&#xff0c;如开关电源&#xff08;SMPS&#xff09;、电池充…

yolov8通过训练完成的模型生成图片热力图--论文需要

源代码来自于网络 使用pytorch_grad_cam&#xff0c;对特定图片生成热力图结果。 安装热力图工具 pip install pytorch_grad_cam pip install grad-cam# get_params中的参数&#xff1a; # weight&#xff1a; # 模型权重文件&#xff0c;代码默认是yolov8m.pt # c…

希亦、添可、石头洗地机哪款好用?2024洗地机深度测评

今年的洗地机市场竞争异常激烈&#xff0c;各大品牌纷纷推出了自己的旗舰产品。这对消费者来说是个好消息&#xff0c;因为有更多的选择空间。然而&#xff0c;面对如此多的优质洗地机&#xff0c;选择合适的一款也成了一种“幸福的烦恼”。 作为一个专业的测评人士&#xff0…

【笔记】【矩阵的二分】668. 乘法表中第k小的数

力扣链接&#xff1a;题目 参考地址&#xff1a;参考 思路&#xff1a;二分查找 把矩阵想象成一维的已排好序的数组&#xff0c;用二分法找第k小的数字。 假设m行n列&#xff0c;则对应一维下标范围是从1到mn&#xff0c;初始&#xff1a; l1; rmn; mid(lr)/2 设mid在第i行&a…

【源码】综合股票币币合约交易所源码/etf交易所源码/美股港股台股交易所源码

支持多国语言 全开源可二开的一个版本&#xff01;支持虚拟货币 ETF 外汇 美股 A股 港股 台股。 前端是VUE开发&#xff08;带vue工程源码&#xff09;后端JAVA开发&#xff01;搭建也相对简单。 总的来说功能非常强大&#xff0c;适合线上运营的一个版本&#xff0c;有兴趣的可…

Linux--08---挂载分区

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.查看系统磁盘分区情况1.lsblk 查看2.fdisk -l 2.挂载未分区磁盘1. 创建分区2. 格式化分区3. 创建挂载点4. 挂载分区5. 更新 /etc/fstab6.验证挂载 3.修改挂载的磁…

样本学习:当AI遇上“少见多怪”

东汉名臣牟融在其著作《牟子》写道&#xff1a;“少所见&#xff0c;多所怪&#xff0c;睹橐驼&#xff0c;谓马肿背。”意思是见闻少的人遇到不常见的事物就觉得奇怪&#xff0c;见到骆驼也以为是背肿了的马。因此&#xff0c;后人总用“少见多怪”来嘲笑见识浅陋的人。然而&a…