Redis的数据 类型
Redis中数据是key-value形式。不同类型Value是有不同的命令进行操作。
key固定是string类型.且不能重复
Value有6中类型: 1. String 字符串2. Hash 哈希表3. List 列表4. Set 集合5. Sorted Set 有序集合.6 Stream类型(Redis5以后新版本类型)
key
1.exists
判断key是否存在。
exists key
返回值:存在返回1,不存在返回0
2.expire
设置key的过期时间,单位秒
expire key 秒数
返回值:成功返回1,失败返回0
3.ttl
查看key的剩余过期时间
ttl key
返回值:返回剩余时间,如果不过期返回-1
4.del
根据key删除键值对。
语法:del key
返回值:被删除key的数量
1.value-string
1.set
设置指定key的值。key不存在则新增,key存在则修改覆盖。键值对是永久存在的。
set key value
返回值:成功返回OK
2.get
获取指定key的值
语法:get key
返回值:key的值。不存在返回nil
3.setnx
当且仅当key不存在时才新增。
setnx key value
返回值:不存在返回1,存在返回0
4.setex
设置key的存活时间,如果存在key覆盖旧值。同时必须指定过期时间。
语法:setex key seconds value
返回值:OK
2.value-哈希表(Hash)
Hash类型的值中包含多组field value。
1.hset
给key中field设置值。
hset key field value
返回值:成功1,失败0
2.hget
获取key中某个field的值
语法:hget key field
返回值:返回field的内容
3.hmset
给key中多个filed设置值
语法:hmset key field value field value
返回值:成功OK
4.hmget
一次获取key中多个field的值
语法:hmget key field field
返回值:value列表
5.hvals
获取key中所有field的值
语法:hvals key
返回值:value列表
6hgetall
获取所有field和value
语法:hgetall key
返回值:field和value交替显示列表
7.hdel
删除key中任意个field
语法:hdel key field field
返回值:成功删除field的数量
3.value-列表(List)
一个键对应多个值
key value1 value2 value3 value4
1.Rpush
向列表末尾中插入一个或多个值
语法;rpush key value1 value2
返回值:列表长度
2.lrange
返回列表中指定区间内的值。可以使用-1代表列表末尾
语法:lrange list 0 -1
返回值:查询到的值
3.lpush
将一个或多个值插入到列表前面
语法:lpush key value1 value2
返回值:列表长度
4.llen
获取列表长度
语法:llen key
返回值:列表长度
5.lrem
删除列表中元素。count为正数表示从左往右删除的数量。负数从右往左删除的数量。
语法:lrem key count value
返回值:删除数量。 注意这个value需要和删除元素value一致才可以删除
4.value-集合(Set)
set和java中set集合类似。不允许重复值,如果插入重复值,后新增返回结果为0。
1.sadd
向集合中添加内容。不允许重复。
语法:sadd key value value value
返回值:集合长度
2.scard
返回集合元素数量
语法:scard key
返回值:集合长度
3.smembers
查看集合中元素内容
语法:smembers key
返回值:集合中元素
5.value-有序集合(Sorted Set)
不允许重复值,有序
有序集合中每个value都有一个分数(score),根据分数进行排序。
1.zadd
向有序集合中添加数据
语法:zadd key score value score value
返回值:长度
2.zrange
返回区间内容,withscores表示带有分数
语法:zrange key 区间 [withscores]
返回值:值列表
value-xrange
根据ID查询出内容。
语法:xrange key ID开始值 ID结束值。
- 代表最小值
- 代表最大值
ID的取值为大于零的整数。
示例:
xrange sxt 0 10 // 查询出id为0到10的
xrange sxt 0 + // 查询出ID从0到最大值
xrange sxt - + // 查询出所有
Redis持久化策略
Redis不仅仅是一个内存型数据库,还具备持久化能力。
Redis每次启动时都会从硬盘存储文件中把数据读取到内存中。运行过程中操作的数据都是内存中的数据。
一共包含两种持久化策略:RDB 和 AOF
1.RDB(Redis DataBase)(保存数据) 恢复快,不安全
rdb模式是默认模式,可以在指定的时间间隔内生成数据快照(snapshot),默认保存到dump.rdb文件中。
当redis重启后会自动加载dump.rdb文件中内容到内存中。用户可以使用SAVE(同步)或BGSAVE(异步)手动保存数据。
可以设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令
可以通过save选项设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行BGSAVE命令。
save 900 1
save 300 10
save 60 10000
服务器在900秒之内,对数据库进行了至少1次修改
服务器在300秒之内,对数据库进行了至少10次修改
服务器在 60秒之内,对数据库进行了至少10000次修改。
优点
rdb文件是一个紧凑文件,直接使用rdb文件就可以还原数据。
数据保存会由一个子进程进行保存,不影响父进程做其他事情。
恢复数据的效率要高于aof
缺点
每次保存点之间导致redis不可意料的关闭,可能会丢失数据。
由于每次保存数据都需要fork()子进程,在数据量比较大时可能会比较耗费性能。
2. AOF(AppendOnly File)(保存命令) 恢复慢,更安全
AOF默认是关闭的,需要在配置文件redis.conf中开启AOF。
Redis支持AOF和RDB同时生效,如果同时存在,AOF优先级高于RDB(Redis重新启动时会使用AOF进行数据恢复)
原理:实时保存用户执行的命令,恢复时执行之前保存的用户的命令
开启:
这个文件是自己创建的
修改redis.conf中。这个文件需要自己创建放到 /usr/local/redis目录下
appendonly yes 开启aof
appendfilename 设置aof数据文件,名称随意。
# 默认no
appendonly yes
# aof文件名
appendfilename "appendonly.aof"
优点
相对RDB数据更加安全。
缺点
相同数据集AOF要大于RDB。
相对RDB可能会慢一些。
SpringBoot整合Spring Data Redis
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.配置yml
spring:
redis:
host: 192.168.52.133
prot: 6379
测试类:
- opsForValue : String值(最常用),如果存储Java对象或Java中集合时就需要使用序列化器,将对象序列化成JSON字符串。
- opsForList : 列表List
- opsForHash: 哈希表Hash
- opsForZSet: 有序集合Sorted Set
- opsForSet : 集合
一.存储普通对象
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Test
public void testString() {
redisTemplate.opsForValue().set("a","1",10, TimeUnit.SECONDS);
redisTemplate.opsForList().rightPushAll("b","1","2","3");
}
二.存储对象
1.实例类上一定要加Serializable接口
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer id;
private String username;
private String password;
}
2.配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
//设置key的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置value的序列化器
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
3.测试
注意RedisTemplate的泛型是<String, Object>
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testString() {
User user = new User(2, "张三", "hello world");
//存
redisTemplate.opsForValue().set("user:2",user);
//取
User u = (User)redisTemplate.opsForValue().get("user:1");
System.out.println("u = " + u);
}
Spring Cache
Spring Cache 是Spring - context-xxx.jar中提供的功能,可以结合EHCache,Redis等缓存工具使用,提供缓存处理,缓存基本判断等操作,可以直接使用注解实现,在包含了Spring - context-xxx.jar的Spring Boot项目中,在启动类中添加@EnableCaching注解,即可开启缓存功能。默认Spring Cache是不开启
Spring Cache加载缓存工具顺序
只要检测到项目中配置了下面缓存工具(导入了依赖,在Spring容器中发现对应工具的内容),无论导入多少个缓存工具依赖,只用优先级最高的一个
默认寻找缓存工具的顺序:(为什么Redis配置上就可以用的原因)
- Generic
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
1.导入依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
2.yml配置文件
spring:
redis:
host: 192.168.8.128
port: 6379 # 默认值,可省略
3.启动类加@EnableCaching注解
@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
}
4.几个注解的使用
Cacheable
适用于查询方法前
- 根据key访问缓存服务器,查到了则直接返回,当前方法不执行,没查到则方法返回值作为value,保存到缓存服务器中
- 完整的缓存key是: cacheNames + “::” + key
- key - 缓存key的后缀.字符串类型,可以使用字符串字面值和SpringEL表达式赋值,赋值的时候,如果是字符串的字面值,必须使用 ’ ’ 标记
1.先去redis中找键为test::fs对应的value,找到了,直接返回方法调用方,没找到,将方法返回值作为value,test::fs作为key保存到redis
@Cacheable(cacheNames = "test",key = "'fs'")
public String show() {
String str = "hello world!";
System.out.println("打赢了hello world");
return str;
}
2.这里注解中的key中可以使用SpringEL表达式赋值
#id : 参数(仅一个参数时使用,且要和参数名一致)
#root.methodName : 代表方法名
......
@Cacheable(cacheNames = "test",key = "'fs' + #id + #root.methodName")
public String show(String id) {
String str = "hello world!";
System.out.println("打赢了hello world");
return str;
}
3.SpringEL中的常见变量有很多
@CachePut
适用于修改方法前
不管是否缓存数据库中有对应的键,一定会执行所在方法.并覆盖原缓存数据库键所对应的值,没有则添加
@CachePut(cacheNames = "test",key = "'fs' + #id + #root.methodName")
public String show(String id) {
String str = "hello world!";
System.out.println("打赢了hello world");
return str;
}
@CacheEvict
适用于删除方法前
当删除数据库数据成功后,也要删除缓存中的数据。避免查询的时候,基于缓存,
根据注解中的key,访问缓存服务器,删除键值对,所在方法一定会执行
allEntries - 布尔类型。是否删除cacheNames作为前缀的所有键值对。默认false。
删除键为test::fs对应的vlaue,对应方法一定会执行
@CacheEvict(cacheNames = "test", key = "'fs'")
public String removeById(Long id) {
String str = "hello world";
return str;
}
删除cacheNames为test的所有键值对。默认false。
@CacheEvict(cacheNames = "test",allEntries = true)
public String show(String id) {
String str = "hello world!";
System.out.println("打赢了hello world");
return str;
}
@CacheConfig(cacheNames = " ")
定义到类上,给当前类所有的使用spring cache的方法添加统一前缀
@Service
@CacheConfig(cacheNames = "test")
public class DemoServiceImpl implements DemoService {}
condition参数
在执行方法之前判断,不能使用方法的返回值进行判断
如果不满足condition中的条件,则 @Cacheable 直接失效,既不去redis中查询,也不保存
@Cacheable(cacheNames = "test",key = "'fs'",condition = "#id.equals('hello')")
public String show(String id) {
String str = "hello world!";
System.out.println("打赢了hello world");
return str;
}
unless
在执行方法之后判断,能使用方法的返回值进行判断
condition作用相反
序列化器
默认情况下存储到redis中数据前面会出现乱码,此乱码不影响使用,判断结果时忽略乱码内容即可。
默认对Redis的value序列化器使用JdkSerializationRedisSerializer序列化器,此序列化器是基于JDK的Serializable实现数据的对象的序列化。
当方法返回值是自定义类型或集合类型的时候也就会出现查看繁琐的问题,这个时候可以更换Redis中value对应的序列化器。更换序列化器后同时也会解决Redis中数据前面出现乱码的问题。
建一个配置类即可
当方法返回值是自定义类型或集合类型的时候也就会出现查看繁琐的问题,这个时候可以更换Redis中value对应的序列化器。更换序列化器后同时也会解决Redis中数据前面出现乱码的问题。@Configuration
public class MySpringCacheConfiguration {
/**
* 创建一个CacheManager,缓存管理器。
* 实现缓存的访问配置管理。
* 如:缓存有效期。键值对的序列化方式等。
* 在SpringCache技术中,要求,一个Spring容器上下文只有唯一的CacheManager对象。
*
* RedisCacheManager - Redis缓存服务器的管理工具。
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
// 创建默认的缓存配置管理。
RedisCacheConfiguration configuration =
RedisCacheConfiguration.defaultCacheConfig();
// 配置,可以提供缓存有效期和键值对序列化器等。
// RedisCacheConfiguration设计比较特殊。每个配置的修改,都会创建一个新的RedisCacheConfiguration对象并返回。
configuration =
configuration
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new StringRedisSerializer()
)
) // 设置key的序列化工具
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()
)
) // 设置value的序列化工具
.entryTtl(Duration.ofMinutes(30L)) // 设置所有键值对的有效期
.disableCachingNullValues() ; // 是否忽略value为null的数据缓存保存过程。
// 使用构建器,默认构建的管理器,是默认配置逻辑。
// 永久保存数据,key是字符串序列化工具。value是JDKSerializable序列化工具
// 可以提供自定义的配置逻辑。 RedisCacheConfiguration
RedisCacheManager redisCacheManager =
RedisCacheManager
.builder() // 构建器。用于构建RedisCacheManager的工具。必须提供连接工厂
.cacheWriter( // 提供连接工厂
RedisCacheWriter.lockingRedisCacheWriter(factory)
)
.cacheDefaults(configuration) // 基于提供的配置,创建管理器。
.build();
return redisCacheManager;
}
}