一、使用docker安装redis :
前置内容:linux云服务器配置及Docker安装
先查看端口是否被占用:lsof -i:6379
docker run --name some-redis -d -it -p 6379:6379 redis --requirepass "密码" --appendonly yes
之后使用docker ps
命令查看redis容器是否成功运行。
记得在云服务器防火墙处开放端口6379
安装QuickRedis进行测试连接
创建连接输入IP地址、端口、密码进行连接测试,出现“连接建立成功”即可。
之后在刚刚建立好的连接处右键点击“打开命令行”,就可以进行redis的相关命令操作了。
二、常用五大基本数据类型
key操作
keys *
:查看当前库所有 keyexists <key>
:判断某个 key 是否存在type <key>
:查看指定的 key 对应的value是什么类型del <key>
:删除指定的 key 数据
> set name orange
OK
> type name
string
> exists name
1
> del name
1
> exists name
0
unlink <key>
:根据 value 选择非阻塞删除,仅将 keys 从 keyspace 元数据中删除,真正的删除会在后续异步操作, 非常不重要的语法expire <key> <10>
:为给定的 key 设置过期时间ttl <key>
:查看还有多少秒过期,-1表示永不过期,-2表示已过期
> get name
orange
> expire name 10
1
> ttl name
8
> ttl name
-2
select 6
:命令切换数据库(Redis默认有16个数据库:从0号到15号,默认使用 0 号数据库)dbsize
:查看当前数据库的 key 的数量flushdb
:清空当前库flushall
:通杀全部库
SELECT 6 将当前客户端链接到第6号库
1、字符串(String)
String 类型是二进制安全的。意味着 Redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。
String 类型是 Redis 最基本的数据类型,一个 Redis 中字符串 value 最多可以是 512M。
set <key> <value>
:添加键值对get <key>
:查询对应键值setex <key> <过期时间> <value>
:设置键值的同时,设置过期时间,单位秒。
> setex home 5 china
OK
> ttl home
2
> ttl home
-2
incr <key>
:重要: 将 key 中储存的数字值增 1,只能对数字值操作,如果为空,新增值为 1(具有原子性)(返回增加后的数字)
> set age 1
OK
> incr age
2
-
append <key> <value>
:将给定的 追加到原值的末尾(了解) -
strlen <key>
:获得值的长度 -
setnx <key> <value>
:只有在 key 不存在时,设置 key 的值 -
decr <key>
:将 key 中储存的数字值减 1,只能对数字值操作,如果为空,新增值为 -1 -
incrby/decrby <key><步长>
:将 key 中储存的数字值增减。自定义步长 -
mset <key1> <value1> <key2> <value2>
:同时设置一个或多个 key-value 对 -
mget <key1> <key2> <key3>...
:同时获取一个或多个 value -
msetnx <key1> <value1> <key2> <value2>...
:同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在(了解) -
getrange <key> <起始位置> <结束位置>
:截取获得String的子字符串 -
setrange <key> <起始位置> <value>
:指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始,返回的数值为修改后的字符串长度。 -
getset <key> <value>
:以新换旧,设置了新值同时获得旧值。
> get name
AppleAndBanana
> getrange name 3 6 从0开始,包括3包括6
leAn
> setrange name 5 orrrr 从第5位开始,覆盖为"orrrr"
14
> get name 覆盖后的name对应的值
Appleorrrrnana
> getset name orange 设置了新值同时获得旧值
AppleorrBanana
> get name
orange
原子性
所谓 原子 操作是指不会被线程调度机制打断的操作;
这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。
- 在单线程中, 能够在单条指令中完成的操作都可以认为是“原子操作”,因为中断只能发生于指令之间。
- 在多线程中,不能被其它进程(线程)打断的操作就叫原子操作。
Redis 单命令的原子性主要得益于 Redis 的大多数操作是单线程。
数据结构
内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配.
2、列表(List)
Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
lrange <mylist> 0 -1
:0表示左边第一个,-1表示右边第一个,(0 -1表示获取所有)lrange <key> <start> <stop>
:按照索引下标获得元素(从左到右)lpush/rpush ….
: 从左边/右边插入一个或多个值。
> lpush k1 v1 v2 v3
3
> lrange k1 0 -1
v3
v2
v1
> rpush k1 v1 v2 v3
3
> lrange k1 0 -1
v1
v2
v3
lpop/rpop <key>
:从左边/右边吐出一个值。值在键在,值光键亡。
> lrange k1 0 -1
v3
v2
v1
> lpop k1
v3
> rpop k1
v1
> rpop k1
v2
> rpop k1
null
rpoplpush <key1><key2>
:从 列表右边吐出一个值,插到 列表左边。
> lrange k1 0 -1
v3
v2
v1
> rpoplpush k1 k1
v1
> lrange k1 0 -1
v1
v3
v2
> lpush group1 aa
1
> lpush group1 bb
2
> lpush group1 ccc dd4 ee5 ff666
6
> lrange group1 0 3
ff666
ee5
dd4
ccc
-
llen <key>
:获得列表长度 -
lindex <key><index>
:按照索引下标获得元素(从左到右,从0开始)
> lrange k1 0 -1
v3
v2
v1
> lindex k1 1
v2
-
linsert <key> before/after <value><newvalue>
:在 的前面/后面插入 插入值 -
lrem <key><n><value>
:从左边删除 n 个 value(从左到右) -
lset <key> <index> <value>
:将列表 key 下标为 index 的值替换成 value
> lrange k1 0 -1
v3
v2
v1
> lset k1 1 v555
OK
> lrange k1 0 -1
v3
v555
v1
> type k1
list
数据结构
List 的数据结构为快速链表 quickList。
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表。
它将所有的元素紧挨着一起存储,分配的是一块连续的内存。
当数据量比较多的时候才会改成 quicklist。
因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的指针 prev 和 next。
Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
3、Set(集合)
Set 对外提供的功能与 List 类似列表的功能,特殊之处在于 Set 是可以 自动排重 的,当需要存储一个列表数据,又不希望出现重复数据时,Set 是一个很好的选择,并且 Set 提供了判断某个成员是否在一个 Set 集合内的重要接口,这个也是 List 所不能提供的。
Redis 的 Set 是 String 类型的无序集合。它底层其实是一个 value 为 null 的 hash 表,所以添加,删除,查找的复杂度都是 O(1)。
一个算法,随着数据的增加,执行时间的长短,如果是 O(1),数据增加,查找数据的时间不变。
-
sadd …..
:将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略 -
smembers <key>
:取出该集合的所有值。 -
sismember <key><value>
:判断集合 是否为含有该 值,有返回 1,没有返回 0 -
scard<key>
:返回该集合的元素个数。 -
srem <key><value1><value2> ....
:删除集合中的某个元素 -
spop <key>
:了解, 随机从该集合中吐出一个值 -
srandmember <key><n>
:随机从该集合中取出 n 个值,不会从集合中删除
> srandmember s1 2
v3
v2
> smembers s1
v3
v2
-
smove <source><destination>value
:把集合中一个值从一个集合移动到另一个集合 -
sinter <key1><key2>
:返回两个集合的交集元素 -
sunion <key1><key2>
:返回两个集合的并集元素 -
sdiff <key1><key2>
:返回两个集合的差集元素(key1 中的,不包含 key2 中的)
数据结构
Set 数据结构是字典,字典是用哈希表实现的。
4、Hash(哈希)
Redis hash 是一个键值对集合。
Redis hash 是一个 String 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
-
hset
:给 集合中的 键赋值 -
hget <key1><field>
:从 集合 取出 value -
hmset <key1> <field1><value1> <field2><value2>...
: 批量设置 hash 的值 -
hmget
… -
hexists <key1><field>
:查看哈希表 key 中,给定域 field 是否存在 -
hkeys <key>
:列出该 hash 集合的所有 field -
hvals <key>
:列出该 hash 集合的所有 value -
hincrby <key><field><increment>
:为哈希表 key 中的域 field 的值加上增量 1 -1 -
hsetnx <key><field><value>
:将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在
以下是一些 Redis Hash 类型的操作示例,包括操作和返回结果:
- 设置哈希表的值:
> hset myhash one hello
1
结果:在名为 myhash
的哈希表中,将 one
的值设置为 “hello”。
- 获取哈希表的值:
> hget myhash one
hello
结果:从名为 myhash
的哈希表中获取 one
的值,返回 “hello”。
- 批量设置哈希表的值:
> hmset myhash two 222 three 33 color red
OK
结果:在名为 myhash
的哈希表中,批量设置多个字段和对应的值。
- 批量获取哈希表的值:
> hmget myhash one two three color
hello
222
33
red
结果:从名为 myhash
的哈希表中批量获取多个字段的值,返回 [“hello”, “222”, “33”,“red”]。
- 检查字段是否存在:
> hexists myhash one
1
> hexists myhash ten
0
结果:检查名为 myhash
的哈希表中是否存在 field1
,返回 1 表示存在,返回 0 表示不存在。
- 列出所有字段:
> hkeys myhash
one
two
three
color
结果:列出名为 myhash
的哈希表中的所有字段。
- 列出所有值:
> hvals myhash
hello
222
33
red
结果:列出名为 myhash
的哈希表中的所有值。
- 增加字段值:
> hincrby myhash three 5
38
结果:将名为 myhash
的哈希表中的 field1
的值增加 5,如果字段不存在,则创建并设置值为 5。
- 设置字段值,仅当字段不存在时:
> hsetnx myhash one "New Value"
0
> hget myhash one
hello
> hsetnx myhash no "New Value"
1
> hget myhash no
New Value
结果:将名为 myhash
的哈希表中的 one
的值设置为 “New Value”,但仅当 one
不存在时。
这些是 Redis Hash 类型的一些常见操作和对应的返回结果案例。可以根据需要在应用程序中使用这些操作来管理和操作哈希表数据。
数据结构
Hash 类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。
当 field-value 长度较短且个数较少时,使用 ziplist,否则使用 hashtable。
hash表结构, 会在java集合源码, hashmap的源码分析的时候说明
5、Zset(有序集合 sorted set)
Redis 有序集合 zset 与普通集合 set 非常相似,是一个没有重复元素的字符串集合。
不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复的。
因为元素是有序的,所以可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
访问有序集合的中间元素也是非常快的,因此能够使用有序集合作为一个没有重复成员的智能列表。
-
zadd …
:先写分数,再写成员。将一个或多个 member 元素及其 score 值加入到有序集 key 当中 -
zrange <key><start><stop> [WITHSCORES]
:返回有序集 key 中,下标在 之间的元素 -
当带 WITHSCORES,可以让分数一起和值返回到结果集
-
zcard<key>
:返回该集合的元素个数。 -
zrangebyscore key min max [withscores] [limit offset count]
:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 -
zrevrangebyscore key max min [withscores] [limit offset count]
:同上,改为从大到小排列 -
zincrby <key><increment><value>
:为元素的 score 加上增量 -
zrem <key><value>
:删除该集合下,指定值的元素 -
zcount <key><min><max>
:统计该集合,分数区间内的元素个数 -
zrank <key><value>
:返回该值在集合中的排名,从 0 开始。
以下是一些 Redis 有序集合(Sorted Set)的操作代码和返回结果案例:
- 添加元素到有序集合:
> zadd myzset 1 "Member1" 2 "Member2" 3 "Member3"
3
结果:将三个成员添加到名为 myzset
的有序集合中,每个成员都有一个分数。
- 获取有序集合中指定范围的成员:
> zrange myzset 0 -1
Member1
Member2
Member3
结果:返回名为 myzset
的有序集合中的所有成员,按照分数从小到大排列。
- 获取有序集合中指定范围的成员和分数:
> zrange myzset 0 -1 withscores
Member1
1
Member2
2
Member3
3
结果:返回名为 myzset
的有序集合中的所有成员和它们的分数。
- 获取有序集合的元素个数:
> zcard myzset
3
结果:返回名为 myzset
的有序集合中的元素个数。
- 根据分数范围获取成员:
> zrangebyscore myzset 1 2
Member1
Member2
结果:返回名为 myzset
的有序集合中分数在 1 和 2 之间的成员。
- 根据分数范围获取成员和分数:
> zrangebyscore myzset 1 2 withscores
Member1
1
Member2
2
结果:返回名为 myzset
的有序集合中分数在 1 和 2 之间的成员和它们的分数。
- 为元素的分数增加指定增量:
> zincrby myzset 2 "Member1"
3
结果:将名为 myzset
的有序集合中 “Member1” 的分数增加 2。
- 删除指定元素:
> zrem myzset "Member2"
1
结果:从名为 myzset
的有序集合中删除 “Member2”。
- 统计分数范围内的元素个数:
> zcount myzset 1 3
2
结果:统计名为 myzset
的有序集合中分数在 1 和 3 之间的元素个数。
- 获取成员在有序集合中的排名:
> zrank myzset "Member1"
0
结果:返回名为 myzset
的有序集合中 “Member1” 的排名,从 0 开始。
这些是 Redis 有序集合的一些常见操作和对应的返回结果案例。有序集合是一种非常有用的数据结构,可用于许多应用程序中的排序和排名需求。
数据结构
SortedSet(zset)是 Redis 提供的一个非常特别的数据结构,一方面它等价于 Java 的数据结构 Map<String, Double>,可以给每一个元素 value 赋予一个权重 score,另一方面它又类似于 TreeSet,内部的元素会按照权重 score 进行排序,可以得到每个元素的名次,还可以通过 score 的范围来获取元素的列表。
zset 底层使用了两个数据结构
- hash,hash 的作用就是关联元素 value 和权重 score,保障元素 value 的唯一性,可以通过元素 value 找到相应的 score 值
- 跳跃表,跳跃表的目的在于给元素 value 排序,根据 score 的范围获取元素列表
三、Jedis操作Redis
- 添加依赖
注意:使用 Jedis 需要添加 Jedis 相关的依赖。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
Jedis 是一个 Java 客户端库,用于连接和操作 Redis 数据库。它提供了丰富的 API,使 Java 开发人员能够轻松地与 Redis 进行交互。以下是一些常见的 Jedis 操作示例:
-
连接到 Redis 服务器:
import redis.clients.jedis.Jedis; // 创建一个 Jedis 连接 Jedis jedis = new Jedis("服务器IP地址", 6379); jedis.auth("redis安装密码"); // 连接成功后会返回 PONG String response = jedis.ping(); System.out.println("Server ping response: " + response);
-
设置和获取键值对:
// 设置一个键值对 jedis.set("myKey", "myValue"); // 获取键对应的值 String value = jedis.get("myKey"); System.out.println("Value for myKey: " + value);
-
操作列表:
// 向列表中添加元素 jedis.lpush("myList", "item1", "item2", "item3"); // 获取列表中的元素 List<String> myList = jedis.lrange("myList", 0, -1); System.out.println("List items: " + myList);
-
操作集合:
// 向集合中添加元素 jedis.sadd("mySet", "member1", "member2", "member3"); // 获取集合中的所有成员 Set<String> mySet = jedis.smembers("mySet"); System.out.println("Set members: " + mySet);
-
操作哈希:
// 向哈希表中设置字段和值 jedis.hset("myHash", "field1", "value1"); jedis.hset("myHash", "field2", "value2"); // 获取哈希表中的字段值 String hashValue = jedis.hget("myHash", "field1"); System.out.println("Hash value for field1: " + hashValue);
-
删除键:
// 删除指定键 jedis.del("myKey");
-
关闭连接:
// 关闭 Jedis 连接 jedis.close();
这些示例涵盖了 Jedis 中的一些常见操作,可以根据需要进行进一步的操作。使用 Jedis 连接到 Redis 数据库,可以执行各种数据操作,如字符串、列表、集合、哈希等,以满足应用程序需求。确保在使用完 Jedis 连接后关闭连接,以释放资源。
四、Spring整合Redis
Spring Data Redis 2.x binaries require JDK level 8.0 and above and Spring Framework 5.3.21 and above. [SpringDataRedis2.x二进制文件需要JDK8.0及以上版本和SpringFramework5.3.21及以上版本。]
redis的2版本必须对应5.3.21以上版本
1、添加依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.7.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope><!--表示test只能在作用域中使用-->
</dependency>
</dependencies>
scope作用域设置为test,使得只在作用域test文件夹下的测试代码可以生效junit
2、添加配置文件spring-ioc.xml
在spring-ioc.xml进行redis服务器IP地址和Redis密码的配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="com.itszt.springredis23"/>
<!-- ioc配置redis-->
<!-- redis连接池的配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大连接持有数量-->
<property name="maxTotal" value="500" /><!-- 属性注入-->
</bean>
<!-- 工厂类配置 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="服务器IP地址" />
<property name="port" value="6379" />
<property name="password" value="Redis密码" />
<property name="poolConfig" ref="jedisPoolConfig" /><!--关联的我们上面配置好的redis连接池对象-->
<property name="timeout" value="15000"></property>
<property name="usePool" value="true"></property>
</bean>
<!-- 核心bean对象: redisTemplate配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 键序列化参数, 指明将来我们spring操作redis的时候, 键只能是存储string类型-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!-- 值序列化参数 指明将来我们spring操作redis的时候, 值只能是存储string类型-->
<!-- 广义的角度来说, 序列化就是出于存储目的, 将某个数据的格式进行转化-->
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<!-- 如果存的是对象,会把对象通过序列化的方式转成字节数组,然后再存储-->
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<!-- 限制redis中hash类型中的值, 可以是任意可序列化对象-->
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
</beans>
1、 String存储
值序列化"valueSerializer","hashKeySerializer"都为“StringRedisSerializer”
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
......
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
String存储的优缺点:
优点: 原封不动的存储, 可读性很好
缺点: 不能存储复杂数据类型, 比如对象
redisTemplate.opsfor有很多与redis对应的方法
String类型 operator(操作)
@Test//String存储
public void test1(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc.xml");
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
//redis有几种常用数据类型
//1. String类型 operator(操作)
ValueOperations operations = redisTemplate.opsForValue();
operations.set("练习内容","添加注解");
Object test1 = operations.get("练习内容");
System.out.println("test1 = " + test1);
}
spring-junit融合
- 添加依赖spring-junit
<!--spring-junit融合-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.27</version>
</dependency>
- 添加两个注解,实现自动读取
spring-ioc.xml
文件中的内容
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-ioc.xml")
public class RedisTemplateTest {
@Autowired
private RedisTemplate redisTemplate;
以上两个注解可以替换掉之前的代码
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-ioc.xml");
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
2、 jdk序列化存储方式对象
User
对象实现序列化接口implements Serializable
@Data
public class User implements Serializable {
private String name;
private String password;
}
值序列化参数 指明将来我们spring操作redis的时候, 值只能是存储string类型
广义的角度来说, 序列化就是出于存储目的, 将某个数据的格式进行转化。
JdkSerializationRedisSerializer
<!-- 核心bean对象: redisTemplate配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!-- 键序列化参数, 指明将来我们spring操作redis的时候, 键只能是存储string类型-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<!-- 值序列化参数 指明将来我们spring操作redis的时候, 值只能是存储string类型-->
<!-- 广义的角度来说, 序列化就是出于存储目的, 将某个数据的格式进行转化-->
<property name="valueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />-->
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
<!-- 如果存的是对象,会把对象通过序列化的方式转成字节数组,然后再存储-->
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<!-- 限制redis中hash类型中的值, 可以是任意可序列化对象-->
<property name="hashValueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>-->
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-ioc.xml")
public class RedisTemplateTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test2(){
User user = new User();
user.setName("王五");
user.setPassword("five");
ValueOperations operations = redisTemplate.opsForValue();
operations.set("酱油组",user);
Object o = operations.get("酱油组");
System.out.println("酱油组o = " + o);
}
在Redis中查看存储的数据
String存储的优缺点:
- 优点: 原封不动的存储, 可读性很好
- 缺点: 不能存储复杂数据类型, 对象
jdk序列化存储方式优缺点:
- 优点: 可以存储任意对象
- 缺点: 不需要的数据也存储了 可读性很差
而json很方便的将对象和字符串进行互相转化
【重点: 几乎所有公司都给redis的序列化设置成了这种格式】
GenericJackson2JsonRedisSerializer
<!--json依赖 jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- 值序列化参数 指明将来我们spring操作redis的时候, 值只能是存储string类型-->
<!-- 广义的角度来说, 序列化就是出于存储目的, 将某个数据的格式进行转化-->
<property name="valueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />-->
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
<!-- 如果存的是对象,会把对象通过序列化的方式转成字节数组,然后再存储-->
</property>
......
<!-- 限制redis中hash类型中的值, 可以是任意可序列化对象-->
<property name="hashValueSerializer">
<!-- <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>-->
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
在redis中查看存储的数据 序列化与json对比