SpringBoot学习之路(六)Redis流程(自定义)

首先添加依赖
<!-- 业务层缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
添加Redis序列化器和反序列化器的配置
@SpringBootConfiguration
public class MyRedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory
factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>(); //创建模板类对象
RedisSerializer<String> redisSerializer = new StringRedisSerializer();//创建String序列化类
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
Jackson2JsonRedisSerializer(Object.class); //指定使用jackson工具负责具体的序列化操作
ObjectMapper om = new ObjectMapper(); //创建jackson的核心api的 ObjectMapper,将bean,list,map,数组等等转成字符串
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 使用objectmapper设置bean的属性,修饰符
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); //设置默认类型
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); //设置将本地时间转成字符串
jackson2JsonRedisSerializer.setObjectMapper(om); //将核心api objectmapper设置给jackson
template.setConnectionFactory(factory); // 通过工厂得到连接对象
template.setKeySerializer(redisSerializer); //设置key序列化方式: 转成字符串
template.setValueSerializer(jackson2JsonRedisSerializer); // 设置value序列化: 字符串
template.setHashValueSerializer(jackson2JsonRedisSerializer); // valuehashmap序列化
return template;
}
}
添加Redis服务器相关配置
spring:
redis:
host: localhost
port: 6379
lettuce:
pool:
max-active: 8
min-idle: 3
通过spring框架提供的模板类RedisTemplate调用API操作Redis数据库
@Service
public class CatalogServiceImpl extends ServiceImpl<CatalogMapper, Catalog>
implements CatalogService {
@Autowired
private RedisTemplate redisTemplate;
private ThreadLocalRandom random = ThreadLocalRandom.current();
@Override
public List<Catalog> listByPage(PageBean pages) {
List<Catalog> res = new ArrayList<>();
9.5、使用postman测试,可以在控制台上查看是否有对应的SQL语句输出以判断缓存是否生效
注解开发
注解提供了更声明式和方便的方式,而编码方式允许更精细的控制和定制。
if (pages == null || pages.getRowsPerPage() < 1) {
//查询所有,避免缓存穿透,索引允许存储数据为空集
if (redisTemplate.hasKey("catalog::all")) {
//如果在具体开发种比较倾向于使用常量的方式
Object obj = redisTemplate.opsForValue().get("catalog::all");
if (obj != null && obj instanceof List)
res = (List<Catalog>) obj;
} else {
res = this.getBaseMapper().selectList(null);
//为了避免雪崩问题,所以生存周期引入随机数
int kk = 100 + random.nextInt(100);
redisTemplate.opsForValue().set("catalog::all", res,
Duration.ofSeconds(kk));
}
} else {
//分页查询。实际上具体应用中不一定针对分页数据进行缓存 catalog::page::size
if (pages.getPageNum() < 1)
pages.setPageNum(1);
String key = "catalog::" + pages.getPageNum() + "::" +
pages.getRowsPerPage();
if (this.redisTemplate.hasKey(key)) {
Object obj = redisTemplate.opsForValue().get(key);
if (obj != null && obj instanceof List)
res = (List<Catalog>) obj;
if(this.redisTemplate.hasKey(key+"::page")){
obj = redisTemplate.opsForValue().get(key+"::page");
if (obj != null && obj instanceof PageBean) {
PageBean tmp = (PageBean) obj;
BeanUtils.copyProperties(tmp,pages);
}
}
}
if (res == null || res.size() < 1) {
Page<Catalog> pageInfo = new Page<>(pages.getPageNum(),
pages.getRowsPerPage());
pageInfo = this.getBaseMapper().selectPage(pageInfo, null);
res = pageInfo.getRecords();
pages.setPageNum(pageInfo.getCurrent());
pages.setRowsNum(pageInfo.getTotal());
pages.setMaxPage(pageInfo.getPages());
int kk = 100 + random.nextInt(100); //随机数时长用于避免雪崩
redisTemplate.opsForValue().set(key, res,
Duration.ofSeconds(kk));
redisTemplate.opsForValue().set(key+"::page", pages,
Duration.ofSeconds(kk));
}
}
return res;
}
}

 

posted @ 2023-07-27 21:03  躺平小伙  阅读(27)  评论(0编辑  收藏  举报