一,将查询结果放到redis中作为缓存,减轻mysql的压力。
只有在数据量大的时候,查询速度慢的时候才有意义。
本次测试的数据量为百万级别。
测试代码: 功能为根据昵称进行模糊匹配。
@GetMapping("/get-by-nick")
public String getNickName(String nickName){
LambdaQueryWrapper<UserPO> wrapper = new LambdaQueryWrapper<UserPO>()
.like(UserPO::getNickName,nickName)
.or()
.like(UserPO::getUserName,nickName);
List<UserPO> userPOS = userMapper.selectList(wrapper);
if (userPOS.isEmpty()){
return "暂无此人";
}
return userPOS.toString();
}
查看数据库查询的时间:
大约是5s,如果是在高并发的情况下,用户的体验感....一个请求等5s......
想到加入redis缓存,修改代码,如果redis中没有那么将查询结果存放到redis中。
这样就不需要再去查询数据库。
@GetMapping("/get-by-nick")
public String getNickName(String nickName){
String key =buildKey(nickName);
if(Boolean.TRUE.equals(redisTemplate.hasKey(key))){
return redisTemplate.boundValueOps(key).get();
}
LambdaQueryWrapper<UserPO> wrapper = new LambdaQueryWrapper<UserPO>()
.like(UserPO::getNickName,nickName)
.or()
.like(UserPO::getUserName,nickName);
List<UserPO> userPOS = userMapper.selectList(wrapper);
if (userPOS.isEmpty()){
redisTemplate.boundValueOps(key).set("暂无此人");
return "暂无此人";
}
redisTemplate.boundValueOps(key).set(userPOS.toString());
return userPOS.toString();
}
二,缓存预热
服务启动的时候将热点数据提前放到redis里面,例如天猫商城双11秒杀,不至于QPS急剧增大将服务瞬间压垮。
示例: 模拟热点数据,在服务启动前,将热点数据查出来放到redis中。
@PostConstruct
public void initCache(){
log.info("=========进行缓存预热=======================");
List<Long> id = Arrays.asList(101110L,101112L,101116L,101118L);
List<UserPO> userPOS = userMapper.selectList(new LambdaQueryWrapper<UserPO>().in(UserPO::getId, id));
userPOS.stream().forEach(item->{redisTemplate.boundValueOps(buildKey(item.getId().toString())).set(item.toString());});
}
三,关于PostConstructor注解
这个注解其实是Java自己的注解。
@PostConstructor用来修饰一个非静态的void方法,调用时机是servlet被服务器加载之前,并且只会执行一次。在构造方法之后执行,init方法之前执行。
通常会在Spring框架中用到此注解,
执行顺序是Constructor(构造器)->@Autowired(依赖注入)->@PostConstructor(注释的方法)
下面我们来测试他的执行顺序。
@Component
public class A {
@Autowired
private B b;
public A(){
System.out.println("A的构造方法");
}
@PostConstruct
private void init(){
System.out.println("postconstructor");
}
}
@Component
class B {
public B(){
System.out.println("B的构造方法");
}
}
使用场景比如说在秒杀中,服务启动时,提前将热点数据查询出来,放到redis缓存中。
如二中所示。