1.缓存菜品
用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大。
/**
* 根据分类id查询菜品
*
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
//构造redis缓存key,规则为:dish_分类id
String key="dish_"+categoryId;
//查找redis中是否存在缓存
List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
//如果存在,直接返回
if(list !=null && list.size()>0){
return Result.success(list);
}
//如果不存在,查询数据库
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
list = dishService.listWithFlavor(dish);
//将查询到的数据载入缓存
redisTemplate.opsForValue().set(key,list);
return Result.success(list);
}
2.清理缓存
清理缓存的逻辑,需要改造的方法(修改管理端接口 DishController 的相关方法):
- 新增菜品(针对性删redis,String key="dish_"+dishDTO.getCategoryId())
- 修改菜品(直接全删redis,传入"dish_*")
- 批量删除菜品(直接全删redis,传入"dish_*")
- 起售、停售菜品(直接全删redis,传入"dish_*")
抽取清理缓存的方法:
3.Spring Cache
导入maven坐标
常用注解:
注解 | 说明 |
@EnableCaching | 开启缓存注解功能,通常加在启动类上 |
@Cacheable | 在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中 |
@CachePut | 将方法的返回值放到缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
@CachePut注解:
//如果使用Spring Cache缓存数据,key的生成:userCache::key
//1.#加形参的属性之类的,或者本身,要与形参对应
//2.或者result,取返回值算key
//3.p0,p1第几个参数
//4.a0,a1第几个参数
//5.root.args[id].id, 第几个参数
@CachePut(cacheNames = "setmealCache",key = "#categoryId"
在用户端接口SetmealController的 list 方法上加入@Cacheable注解:
这里key不能是result
@CacheEvict(cacheNames="",key="")
删除所有缓存@CacheEvict(cacheNames="",allEntries=true)
4.缓存套餐
具体的实现思路如下:
•导入Spring Cache和Redis相关maven坐标
•在启动类上加入@EnableCaching注解,开启缓存注解功能
•在用户端接口SetmealController的 list 方法上加入@Cacheable注解
•在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解
在用户端接口SetmealController的 list 方法上加入@Cacheable注解:
在管理端接口SetmealController的 save、delete、update、startOrStop等方法上加入CacheEvict注解:
5.添加购物车
根据添加购物车接口创建ShoppingCartController:
@RestController
@RequestMapping("/user/shoppingCart")
@Slf4j
@Api(tags = "C端购物车相关接口")
public class ShoppingCartController {
@Autowired
private ShoppingCartService shoppingCartService;
/**
* 添加购物车
* @param shoppingCartDTO
* @return
*/
@PostMapping("/add")
@ApiOperation("添加购物车")
public Result add(@RequestBody ShoppingCartDTO shoppingCartDTO){
log.info("添加购物车,商品信息为:{}",shoppingCartDTO);
shoppingCartService.addShoppingCart(shoppingCartDTO);
return Result.success();
}
}
创建ShoppingCartServiceImpl实现类,并实现add方法:
@Service
@Slf4j
public class ShoppingCartServiceImpl implements ShoppingCartService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Autowired
private DishMapper dishMapper;
@Autowired
private SetmealMapper setmealMapper;
/**
* 添加购物车
* @param shoppingCartDTO
*/
public void addShoppingCart(ShoppingCartDTO shoppingCartDTO) {
//判断当前加入购物车的商品是否已经存在了
ShoppingCart shoppingCart=new ShoppingCart();
BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
Long userId = BaseContext.getCurrentId();
shoppingCart.setUserId(userId);
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
//只有两种结果:1.查到了只有一条数据2.查不到,无数据
//如果已经存在,只需要数量加1
if (list !=null && list.size() >0){
ShoppingCart cart=list.get(0);
cart.setNumber(cart.getNumber()+1);//update shopping_cart set number=? where id =?
shoppingCartMapper.updateNumberById(cart);
}else{
//如果不存在,需要插入一条购物车数据
Long dishId = shoppingCart.getDishId();
//判断本次添加的是菜品还是套餐
if (dishId != null){
//本次添加到购物车的是菜品
Dish dish = dishMapper.getById(dishId);
shoppingCart.setName(dish.getName());
shoppingCart.setImage(dish.getImage());
shoppingCart.setAmount(dish.getPrice());
}else{
//本次添加到购物车的是套餐
Long setmealId = shoppingCartDTO.getSetmealId();
Setmeal setmeal = setmealMapper.getById(setmealId);
shoppingCart.setName(setmeal.getName());
shoppingCart.setImage(setmeal.getImage());
shoppingCart.setAmount(setmeal.getPrice());
}
shoppingCart.setNumber(1);
shoppingCart.setCreateTime(LocalDateTime.now());
shoppingCartMapper.insert(shoppingCart);
}
}
}
创建ShoppingCartMapper接口:
@Mapper
public interface ShoppingCartMapper {
/**
* 动态条件查询
* @param shoppingCart
* @return
*/
List<ShoppingCart> list(ShoppingCart shoppingCart);
/**
* 根据id修改商品数量
* @param shoppingCart
*/
@Update("update shopping_cart set number = #{number} where id = #{id}")
void updateNumberById(ShoppingCart shoppingCart);
/**
* 插入购物车shopping_cart数据
* @param shoppingCart
*/
@Insert("insert into shopping_cart(name, image, user_id, dish_id, setmeal_id, dish_flavor, amount, create_time) "+
"values (#{name},#{image},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{amount},#{createTime})")
void insert(ShoppingCart shoppingCart);
}
创建ShoppingCartMapper.xml:
一开始and写成了add,一直报错。。。
<mapper namespace="com.sky.mapper.ShoppingCartMapper">
<select id="list" resultType="com.sky.entity.ShoppingCart">
select * from shopping_cart
<where>
<if test="userId !=null">
and user_id=#{userId}
</if>
<if test="setmealId !=null">
and setmeal_id=#{setmealId}
</if>
<if test="dishId !=null">
and dish_id=#{dishId}
</if>
<if test="dishFlavor !=null">
and dish_flavor=#{dishFlavor}
</if>
</where>
</select>
</mapper>
6.查看购物车
在ShoppingCartController中创建查看购物车的方法:
/**
* 查看购物车
* @return
*/
@GetMapping("/list")
@ApiOperation("查看购物车")
public Result<List<ShoppingCart>> list(){
List<ShoppingCart> list= shoppingCartService.showShoppingCart();
return Result.success(list);
}
在ShoppingCartServiceImpl中实现查看购物车的方法:
public List<ShoppingCart> showShoppingCart() {
//获取到当前微信用户id
Long userId = BaseContext.getCurrentId();
ShoppingCart shoppingCart = ShoppingCart.builder()
.userId(userId)
.build();
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
return list;
}
7.清空购物车
在ShoppingCartController中创建清空购物车的方法:
/**
* 清空购物车
* @return
*/
@DeleteMapping("/clean")
@ApiOperation("清空购物车")
public Result clean(){
shoppingCartService.cleanShoppingCart();
return Result.success();
}
在ShoppingCartServiceImpl中实现清空购物车的方法:
public void cleanShoppingCart() {
Long userId = BaseContext.getCurrentId();
shoppingCartMapper.deleteByUserId(userId);
}
在ShoppingCartMapper接口中创建删除购物车数据的方法:
/**
* 根据用户id删除购物车数据
* @param userId
*/
@Delete("delete from shopping_cart where user_id=#{userId}")
void deleteByUserId(Long userId);
8.删除购物车中的一个商品
ShoppingCartController
/**
* 删除购物车中一个商品
* @param shoppingCartDTO
* @return
*/
@PostMapping("/sub")
@ApiOperation("删除购物车中一个商品")
public Result sub(@RequestBody ShoppingCartDTO shoppingCartDTO){
log.info("删除购物车中一个商品:{}",shoppingCartDTO);
shoppingCartService.subShoppingCart(shoppingCartDTO);
return Result.success();
}
ShoppingCartServiceImpl
注意:
//查询当前购物车数据 ShoppingCart shoppingCart=new ShoppingCart(); BeanUtils.copyProperties(shoppingCartDTO,shoppingCart); Long userId = BaseContext.getCurrentId(); shoppingCart.setId(userId); //实际获取的只是点击的那个购物车数据 List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
这段中实际是点减时请求的查询当前这条购物车数据,所以list只有一条数据
/**
* 删除购物车中一个商品
* @param shoppingCartDTO
*/
public void subShoppingCart(ShoppingCartDTO shoppingCartDTO) {
//查询当前购物车数据
ShoppingCart shoppingCart=new ShoppingCart();
BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
Long userId = BaseContext.getCurrentId();
shoppingCart.setId(userId);
//实际获取的只是点击的那个购物车数据
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
if (list !=null &&list.size()>0){
shoppingCart = list.get(0);
Integer number = shoppingCart.getNumber();
if (number==1){
//如果当前商品在购物车数量为1,直接删除
shoppingCartMapper.deleteById(shoppingCart.getId());
}else{
//如果当前商品在购物车数量不为1,修改数量
shoppingCart.setNumber(number-1);
shoppingCartMapper.updateNumberById(shoppingCart);
}
}
}
ShoppingCartMapper
/**
* 根据id删除购物车数据
* @param id
*/
@Delete("delete from shopping_cart where id=#{id}")
void deleteById(Long id);