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 目录
    在这里插入图片描述

使用客户端访问

三、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字符串,实际开发也推荐使用此种方式。
    在这里插入图片描述
  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值