redis的企业开发:
1 代码实现 springdataRedis 例:菜品(mysql-redis的数据一致性)
2 注解实现 SpringCache 例:套餐(mysql-redis的数据一致性)
代码实现
环境配置
1.引入依赖
<!--引入redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.yml中添加配置
spring:
redis:
host: localhost
port: 6379
database: 0
代码实现
1.发送验证码:
@Autowired
private StringRedisTemplate stringRedisTemplate;
// 发送短信
@PostMapping(name = "发送短信验证码",value = "/user/sendMsg")
public ResultInfo sendSmS(@RequestBody Map<String,String> param,
HttpSession session){
//获取到给哪个手机号发送短信
String phone = param.get("phone"); //手机号
// 发送短息
String code = RandomUtil.randomNumbers(6); //验证码
//smsTemplate.sendSms(phone,code); //发送短息(玩完一次就注释掉)
System.out.println("短信验证码:"+code);
//redis优化代码:将验证码放入redis中 有效期1分钟
stringRedisTemplate.opsForValue().set("sms_"+phone,code,1, TimeUnit.MINUTES);
return ResultInfo.success(null);
}
2.校验验证码
// 登录注册
@PostMapping(name="登录/注册实现",value = "/user/login")
public ResultInfo login(@RequestBody Map<String,String> param,
HttpSession session){
// 对比验证码
String phone = param.get("phone"); //获取页面填写的手机号
String code = param.get("code"); //获取页面填写的验证码
//redis优化代码:从redis中获取验证码
String phone_code =stringRedisTemplate.opsForValue().get("sms_"+phone);
if(phone_code==null){
//验证码过期
return ResultInfo.error("验证码已过时,请重新发送验证码");
}
if(!StrUtil.equals(code,phone_code))
{
//验证码不一致
return ResultInfo.error("验证码有误,请重新输入");
}
// 实现登录或者注册
User user = userService.login(phone);
//登录用户存入session
session.setAttribute(Constant.SESSION_USER,user);
//redis优化代码:登录成功后清空redis中的验证码
stringRedisTemplate.delete("sms_"+phone);
// 返回
return ResultInfo.success(user);
}
3.查询-缓存菜品数据
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public List<Dish> findDishList(long categoryId,int status) throws JsonProcessingException {
Boolean flg = stringRedisTemplate.hasKey("dish_" + categoryId);
if(flg==true){
//从redis中获取数据
String json = stringRedisTemplate.opsForValue().get("dish_" + categoryId);
List<Dish> list = new ObjectMapper().readValue(json, List.class);
System.out.println("我是从redis中获取的..");
return list;
}else {
//从mysql查询数据
List<Dish> dishList = dishMapper.selectList(qw);
...
// 放入redis中
String json = new ObjectMapper().writeValueAsString(dishList);
stringRedisTemplate.opsForValue().set("dish_"+categoryId,json);
System.out.println("我是从mysql中获取的..");
return dishList;
}
}
4.新增/修改/删除菜品缓存(保证数据库中的数据和缓存中的数据一致)
@Autowired
private StringRedisTemplate stringRedisTemplate;
//1 菜品新增
public void addCategory(Dish dish) {
//1 先保存一条菜品数据
System.out.println(dish.getId()); //null
dishMapper.insert(dish); //保存数据的主键会自动赋值给该对象id(mp自动支持主键返回策略)
System.out.println(dish.getId());
......
//新增了分类菜品,删除redis中缓存的分类菜品
stringRedisTemplate.delete("dish_"+dish.getCategoryId());
}
//2 菜品删除
@Override
public void deleteDish(List<Long> ids) {
//1 菜品删除
dishMapper.deleteBatchIds(ids);
......
//将redis缓存的菜品缓存都删除
Set<String> set = stringRedisTemplate.keys("dish_*");
stringRedisTemplate.delete(set);
}
//3 菜品修改
@Override
public void updateDish(Dish dish) {
// 1 修改菜品
dishMapper.updateById(dish);
List<DishFlavor> flavorList = dish.getFlavors();
......
//将redis缓存的菜品缓存都删除
Set<String> set = stringRedisTemplate.keys("dish_*");
stringRedisTemplate.delete(set);
}
SpringCache注解实现
springboot使用缓存常用注解:
名称 | 解释 |
---|---|
@EnableCaching | 开启基于注解的缓存 |
@Cacheable | 主要针对查询方法配置,在方法执行前先查看缓存中是否有数据,如果有则直接返回;若没有,调用方法并将方法返回值放到缓存中 |
@CacheEvict | 清空缓存 |
缓存使用
启动类上添加 @EnableCashing
代码演示
实现思路
- 在启动类上加入@EnableCaching注解,开启缓存注解功能
- 在SetmealServicer的list方法上加入@Cacheable注解
- 在SetmealServicer的save和delete方法上加入@CacheEvict注解
@Cacheable注解
@Override
@Cacheable(value = "setmeal",key = "#categoryId")
public List<Setmeal> setmealList(Long categoryId, Integer status) {
System.out.println("查询mysql数据库..");
// 1.构建条件
LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Setmeal::getCategoryId, categoryId);
wrapper.eq(Setmeal::getStatus, status);
// 2.执行查询
List<Setmeal> setmealList = setmealMapper.selectList(wrapper);
// 3.返回结果
return setmealList;
}
@CacheEvict注解
新增、修改、删除方法上添加
// 套餐新增
@Override
@CacheEvict(value = "setmeal",key = "#setmeal.categoryId")
public void save(Setmeal setmeal) {
setmealMapper.insert(setmeal);
}
// 套餐删除
@Override
@CacheEvict(value = "setmeal",allEntries = true)
public void deleteBatchIds(List<Long> ids) {
//删除套餐
setmealMapper.deleteBatchIds(ids);
}
// 套餐更新
@Override
@CacheEvict(value = "setmeal",allEntries = true)
public void update(Setmeal setmeal) {
//根据主键更新菜品表信息
setmealMapper.updateById(setmeal);
}