苍穹外卖Day07
1.1菜品缓存
1.1.1问题和解决方法
用户端小程序展示菜品主要通过查询数据库获取,每一次用户点击分类都是一次查询操作,用户量比较大的时候,数据库压力也会随之增大
问题解决:通过Redis来缓存菜品数据,减少数据库的查询操作
基本逻辑:开始查询菜品->查询缓存是否存在,如果存在读取缓存,如果不存在则查询数据库,并将查询数据载入到缓存中
1.1.2缓存代码实现
user/DishController
// 查询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);//查询起售中的菜品
// 如果不存在则查询数据并讲数据加载到Redis中
list = dishService.listWithFlavor(dish);
redisTemplate.opsForValue().set(key, list);
return Result.success(list);
}
当数据库有改动的时候就不能再使用缓存数据了,因为数据不一致所以当数据库进行增删改操作的时候需要进行清理缓存数据操作,代码如下
// 清理缓存数据
Set keys=redisTemplate.keys("dish_");
redisTemplate.delete(keys);
/**
* 新增菜品
*
* @param dishDTO
*/
@PostMapping
@ApiOperation("新增菜品")
public Result save(@RequestBody DishDTO dishDTO) {
log.info("新增菜品:{}", dishDTO);
dishService.saveWithFlavor(dishDTO);
// 清理缓存
String key = "dish" + dishDTO.getCategoryId();
redisTemplate.delete(key);
return Result.success();
}
1.2借助框架Spring Cache实现缓存
1.2.1实现思路
- 导入Spring Cache和Redis相关的maven坐标
- 在启动类上面加入@EnableCaching的注解,开启缓存注解功能
- 在用户端接口SetmealController的list方法上加入@Cacheable注解
- 在管理端接口SetmealController的save update startOrStop等方法上加入@Cacheable注解
1.2.2代码实现
SkyApplication
@SpringBootApplication
@EnableTransactionManagement //开启注解方式的事务管理
@Slf4j
//开启缓存注解
@EnableCaching
public class SkyApplication {
public static void main(String[] args) {
SpringApplication.run(SkyApplication.class, args);
log.info("server started");
}
}
user/SetmealController
@GetMapping("/list")
@ApiOperation("根据分类id查询套餐")
@Cacheable(cacheNames = "setmealCache",key = "#categoryId")
public Result<List<Setmeal>> list(Long categoryId) {
Setmeal setmeal = new Setmeal();
setmeal.setCategoryId(categoryId);
setmeal.setStatus(StatusConstant.ENABLE);
List<Setmeal> list = setmealService.list(setmeal);
return Result.success(list);
}
admin/SetMealController
@DeleteMapping
@ApiOperation("删除套餐")
@CacheEvict(cacheNames = "setmealCache",allEntries = true)
public Result delete(@RequestParam List<Long> ids) {
log.info("删除套餐:{}", ids);
setMealService.deleteBatch(ids);
return Result.success();
}
其余管理段方法基本类似不做代码演示
2购物车
2.1添加购物车
购物车较容易理解不做过多解释
逻辑分析:
- 对于没有口味的菜品,呈现加号,对于有口味的菜品呈现选择口味的按钮
- 对于已经存在购物车里的菜品,点击添加只会使得购物车数量+1,如果购物车内没有此菜品则添加入购物车
2.2添加购物车代码实现
ShoppingCartController
/**
* @author EllieHy
*/
@RestController
@RequestMapping("/user/shoppingCart")
@Api("购物车相关接口")
@Slf4j
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();
}
}
ShoppingCartService
/**
* @author EllieHy
*/
public interface ShoppingCartService {
void addShoppingCart(ShoppingCartDTO shoppingCartDTO);
}
ShoppingCartServiceImpl
/**
* @author EllieHy
*/
@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) {
// 判断加入购物车的商品是否存在 如果已经存在只需要数量加1即可
ShoppingCart shoppingCart = new ShoppingCart();
BeanUtils.copyProperties(shoppingCartDTO, shoppingCart);
Long userId = BaseContext.getCurrentId();
shoppingCart.setUserId(userId);
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
if (list != null && list.size() > 0) {
ShoppingCart cart1 = list.get(0);
cart1.setNumber(cart1.getNumber() + 1);
shoppingCartMapper.updateNumberById(cart1);
} else {
// 如果不存在实行加入购物车操作
// 判断本次加入到购物车的是菜品还是套餐
Long dishId = shoppingCartDTO.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);
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
/**
* @author EllieHy
*/
@Mapper
public interface ShoppingCartMapper {
/**
* 购物车查询
*
* @param shoppingCart
* @return
*/
List<ShoppingCart> list(ShoppingCart shoppingCart);
/**
* 根据商品来修改购物车商品数量
*
* @param shoppingCart
*/
@Update("update sky_take_out.shopping_cart set number=#{number} where id=#{id}")
void updateNumberById(ShoppingCart shoppingCart);
/**
* 添加购物车
*
* @param shoppingCart
*/
@Insert("insert into sky_take_out.shopping_cart (name, user_id, dish_id, setmeal_id, dish_flavor, number, amount, image, create_time) " +
" values (#{name},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{number},#{amount},#{image},#{createTime})")
void insert(ShoppingCart shoppingCart);
}
ShoppingCartMapper.xml
<select id="list" resultType="com.sky.entity.ShoppingCart">
select *from sky_take_out.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>
2.3购物车查看
比较简单直接上代码
2.4购物车查看代码实现
ShoppingCartController.java
/**
* 查看购物车
* @return
*/
@GetMapping("/list")
@ApiOperation("查询购物车")
public Result<List<ShoppingCart>> list() {
log.info("查询购物车");
List<ShoppingCart> list = shoppingCartService.showShoppingCart();
return Result.success(list);
}
ShoppingCartService.java
/**
* 查看购物车
* @return
*/
List<ShoppingCart> showShoppingCart();
ShoppingCartServiceImpl.java
/**
* 查看购物车
*/
@Override
public List<ShoppingCart> showShoppingCart() {
Long userId=BaseContext.getCurrentId();
ShoppingCart shoppingCart = ShoppingCart.builder().userId(userId).build();
return shoppingCartMapper.list(shoppingCart);
}
2.5清空购物车代码演示
ShoppingCartController.java
/**
* 清空购物车
* @return
*/
@DeleteMapping("/clean")
@ApiOperation("清空购物车")
public Result clean(){
log.info("清空购物车");
shoppingCartService.cleanShoppingCart();
return Result.success();
}
ShoppingCartService
/**
* 清空购物车
*/
void cleanShoppingCart();
ShoppingCartServiceImpl
/**
* 清空购物车
*/
@Override
public void cleanShoppingCart() {
// 获得当前用户id
Long userId=BaseContext.getCurrentId();
shoppingCartMapper.delete(userId);
}
ShoppingCartMapper
/**
* 清空购物车
* @param userId
*/
@Delete("delete from sky_take_out.shopping_cart where user_id=#{userId}")
void delete(Long userId);
pingCartServiceImpl
/**
* 清空购物车
*/
@Override
public void cleanShoppingCart() {
// 获得当前用户id
Long userId=BaseContext.getCurrentId();
shoppingCartMapper.delete(userId);
}
ShoppingCartMapper
/**
* 清空购物车
* @param userId
*/
@Delete("delete from sky_take_out.shopping_cart where user_id=#{userId}")
void delete(Long userId);