用缓存:提前把数据取出来保存好(通常保存到读写更快的介质,比如内存),就可以更快地读写。
分布式缓存
java的进程缓存
单机缓存
数据不一致
解决方法:主从复制
Redis可以作为分布式缓存
NoSQL数据库
key-value存储系统(区别于MySQL存储的键值对)
Spring Data Redis(推荐)
通用的数据访问框架、提供了一组增删改查的接口
操作mysql、redis
引入依赖
org.springframework.session
spring-session-data-redis
2.6.3
yml
spring:
redis:
host: localhost
port: 6379
database: 0
String 字符串类型:name:“aaa”
List列表:names:[“aaa”,“aab”,“aaa”]
Set集合: names:[“aa”,“ab”]
Hash哈希:nameAge:{“aa”:1,“dd”:2}
Zset集合:names:{aaa-9,bbb-12}适合做排行榜
redis也可以做消息队列
bloomfilter(布隆过滤器,主要从大量的数据中快速过滤值,比如邮件黑名单拦截)
geo(计算地理位置)
hyperloglog(pv / uv)
pub / sub(发布订阅,类似消息队列)
BitMap (1001010101010101010101010101)
测试一下
package com.bo.partner.service;
import com.bo.partner.model.domain.User;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author: bo
* @date: 2022/9/12
* @description:
*/
@SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedis() {
ValueOperations value = redisTemplate.opsForValue();
value.set("aaaString", "aka");
value.set("aaaint", 1);
value.set("aaadouble", 2.0);
User user = new User();
user.setId(1L);
user.setUsername("aaa");
value.set("aauser",user);
Object aaaString = value.get("aaaString");
Assertions.assertTrue("aka".equals((String)aaaString));
Object aaaint = value.get("aaaint");
Assertions.assertTrue(1==((Integer)aaaint));
Object aaadouble = value.get("aaadouble");
Assertions.assertTrue(2.0==((Double)aaadouble));
System.out.println(value.get("aauser"));
}
}
报错,空指针异常,解决方法:加个注解@RunWith(SpringRunner.class)
用quickredis查看
怎么回事
看看redisTempalte干了什么
redisTemplate序列化了
if序列化器是空,用的java原生的序列化器
我们加个泛型
@Resource
private RedisTemplate redisTemplate;
没什么用
我们用StringRedisTemplate
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
public void testRedis() {
ValueOperations value = stringRedisTemplate.opsForValue();
但是其他类型的不行了
注释掉其他的
成功
但是没有其他的实现类
写一个配置类吧
package com.bo.partner.config;
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.RedisSerializer;
/**
* @author: bo
* @date: 2022/9/13
* @description:
*/
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(RedisSerializer.string());
return redisTemplate;
}
}
再改回用redisTemplate
运行成功
redisTemplate默认用了Lettuce
点进去
独立于spring操作redis
高阶的操作redis的客户端
异步、连接池
复用连接
分布式操作redis的java客户端
让你像在本地使用集合一样操作redis
分布式数据网格
不同用户看到的数据不同
systemId:moduleId:func:options(不要和别人冲突)光userid容易冲突
partner:user:recommed:userId
redis 内存不能无限增加,一定要设置过期时间!!!
User loginUser = userService.getLoginUser(request);
ValueOperations valueOperations = redisTemplate.opsForValue();
String redisKey = String.format("partner:user:recommed:userId",loginUser.getId());
//如果有缓存。查缓存
Page page = (Page) valueOperations.get(redisKey);
if (page != null) {
return ResultUtils.success(page);
}
//没缓存继续查数据库
//不登录也推荐,但是不个性化,每个人一样
//登录之后就个性化推荐
QueryWrapper queryWrapper = new QueryWrapper<>();
page = userService.page(new Page<>(pageNum,pageSize), queryWrapper);
//写缓存
try {
valueOperations.set(redisKey,page);
} catch (Exception e) {
log.error("redis set key error", e);
}
}
不能用户每天看到的一样推荐
设置下过期时间
测试一下
10s过期
删除下之前的key
重新发请求
10s之后就没了