当前位置: 首页 > news >正文

网站制作广告科技型中小企业服务平台

网站制作广告,科技型中小企业服务平台,网站 反链,江苏住房和城乡建设网站目录 一、缓存菜品 1 问题说明 2 实现思路 3 代码开发#xff1a;修改DishServiceImpl 4 功能测试 二、SpringCache 1. 介绍 2. 使用语法 1 起步依赖 2 使用要求 3 常用注解 4 SpEL表达式(了解备用) 5 步骤小结 3.入门案例 1 准备环境 2 使用入门 1 引导类上加…目录 一、缓存菜品 1 问题说明 2 实现思路 3 代码开发修改DishServiceImpl 4 功能测试 二、SpringCache 1. 介绍 2. 使用语法 1 起步依赖 2 使用要求 3 常用注解 4 SpEL表达式(了解备用) 5 步骤小结 3.入门案例 1 准备环境 2 使用入门 1 引导类上加EnableCaching 2 更新缓存加CachePut CachePut 说明 使用示例 3 使用缓存加Cacheable 测试效果 4 清理缓存加CacheEvict 4. 使用小结 三、缓存套餐 1 问题说明 2 实现思路 3 代码开发 1 添加依赖坐标 2 修改引导类加EnableCaching 3 修改SetmealServiceImpl 浏览套餐时使用缓存 套餐变更时清理缓存 4 功能测试 四、添加购物车 1. 需求分析和设计 1 产品原型 2 接口设计 3 表设计 2. 代码开发 1 DTO设计 2 ShoppingCartController 3 ShoppingCartService 4 ShoppingCartServiceImpl 5 ShoppingCartMapper 6 ShoppingCartMapper.xml 3. 功能测试 五、查看购物车 1. 需求分析和设计 1 产品原型 2 接口设计 2. 代码开发 1 ShoppingCartController 2 ShoppingCartService 3 ShoppingCartServiceImpl 4 ShoppingCartMapper 3. 功能测试 六、清空购物车 1. 需求分析和设计 1 产品原型 2 接口设计 2. 代码开发 1 ShoppingCartController 2 ShoppingCartService 3 ShoppingCartServiceImpl 4 ShoppingCartMapper 3. 功能测试 七、删除购物车中一个商品 一、缓存菜品 1 问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得如果用户端访问量比较大数据库访问压力随之增大。 2 实现思路 通过Redis来缓存菜品数据减少数据库查询操作。 缓存逻辑分析 每个分类下的菜品保存一份缓存数据 数据库中菜品数据有变更时清理缓存数据 要做的事情使用缓存优化菜品相关的性能 给用户端的功能增加缓存查询菜品时优先使用缓存 管理端功能增删改时要清理缓存新增、修改、删除、上下架操作都要清理缓存 3 代码开发修改DishServiceImpl 修改queryUserDishesByCategoryId方法增加缓存 Autowired private StringRedisTemplate redisTemplate;Override public ListDishVO queryUserDishesByCategoryId(Long categoryId) {//↓↓↓↓↓增加代码先从Redis中查询缓存 start↓↓↓↓↓String cacheKey dish: categoryId;String dishesJson redisTemplate.opsForValue().get(cacheKey);if (dishesJson ! null !.equals(dishesJson)) {return JSON.parseArray(dishesJson, DishVO.class);}//↑↑↑↑↑增加代码先从Redis中查询缓存 end↑↑↑↑↑//1. 查询菜品列表及每个菜品关联的分类名称ListDishVO dishVOList dishMapper.selectEnableListByCategoryId(categoryId);//2. 查询每个菜品关联的口味列表for (DishVO dishVO : dishVOList) {//查询口味列表ListDishFlavor dishFlavors dishFlavorMapper.selectListByDishId(dishVO.getId());dishVO.setFlavors(dishFlavors);}//↓↓↓↓↓增加代码把数据缓存到Redis里 start↓↓↓↓↓redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(dishVOList));//↑↑↑↑↑增加代码把数据缓存到Redis里 end↑↑↑↑↑ return dishVOList; } 菜品变化时清理缓存 为了保证数据库和Redis中的数据保持一致修改管理端接口 DishController 的相关方法加入清理缓存逻辑。 需要改造的方法 新增菜品 修改菜品 批量删除菜品 起售、停售菜品 新增菜品时清理缓存 修改方法增加清理缓存的代码 Override Transactional public Result addDish(DishDTO dto) {//1. 把菜品信息存储到dish表里Dish dish new Dish();BeanUtils.copyProperties(dto, dish);dishMapper.insert(dish);//2. 把菜品关联的口味保存到dish_flavors表里每个dishFlavor都要使用到dish的idListDishFlavor flavors dto.getFlavors();if (flavors ! null flavors.size() 0) {//把菜品的id设置给每个DishFlavor对象for (DishFlavor flavor : flavors) {flavor.setDishId(dish.getId());}// flavors.forEach(dishFlavor - dishFlavor.setDishId(dish.getId()));//把DishFlavor对象的集合保存到数据库里才有dishId值// INSERT INTO dish_flavor (dish_id, name, value) VALUES (菜品id,?,?),(),(),(),...;dishFlavorMapper.batchInsert(flavors);}//↓↓↓↓↓增加代码清理缓存↓↓↓↓↓redisTemplate.delete(dish: dto.getCategoryId());//↑↑↑↑↑增加代码清理缓存↑↑↑↑↑return Result.success(); } 删除菜品时清理缓存 修改方法增加清理缓存的代码 Override Transactional public Result batchDeleteByIds(ListLong ids) {//如果有某个菜品状态是“起售”的就抛异常不允许删除int count dishMapper.selectEnableDishCountByIds(ids);if (count 0) {throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);}//如果有某个菜品关联了套餐就抛异常不允许删除count setmeatlDishMapper.selectCountByDishIds(ids);if (count 0) {throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);}//删除这些菜品dishMapper.batchDeleteByIds(ids);//删除这些菜品对应口味列表dishFlavorMapper.batchDeleteByDishIds(ids);//↓↓↓↓↓增加代码清理缓存↓↓↓↓↓SetString keys redisTemplate.keys(dish:*);redisTemplate.delete(keys);//↑↑↑↑↑增加代码清理缓存↑↑↑↑↑return Result.success(); } 修改菜品时清理缓存 修改方法增加清理缓存的代码 Override Transactional public Result updateDishById(DishDTO dto) {//1. 先修改菜品信息Dish dish new Dish();BeanUtils.copyProperties(dto, dish);dishMapper.updateById(dish);//2. 删除菜品关联的口味列表创建一个集合只放一个元素进去怎么实现Collections.singletonList(元素值)dishFlavorMapper.batchDeleteByDishIds(Collections.singletonList(dto.getId()));//3. 把客户端提交的口味列表重新添加到数据库表ListDishFlavor flavors dto.getFlavors();for (DishFlavor flavor : flavors) {flavor.setDishId(dish.getId());}dishFlavorMapper.batchInsert(flavors);//↓↓↓↓↓增加代码清理缓存↓↓↓↓↓redisTemplate.delete(dish: dto.getCategoryId());//↑↑↑↑↑增加代码清理缓存↑↑↑↑↑return Result.success(); } 4 功能测试 可以通过如下方式进行测试 查看控制台sql 前后端联调 查看Redis中的缓存数据 浏览菜品时使用缓存 以加入缓存、菜品修改两个功能测试为例通过前后端联调方式查看控制台sql的打印和Redis中的缓存数据变化。 当第一次查询某个分类的菜品时会从数据为中进行查询同时将查询的结果存储到Redis中在后绪的访问若查询相同分类的菜品时直接从Redis缓存中查询不再查询数据库。 登录小程序选择某一个菜品分类例如蜀味牛蛙(id17)。 第一次点击访问 服务端控制台里输出了SQL语句说明执行了SQL语句是从数据库里查询的 查看Redis里有 dish:17 对应的菜品数据说明数据已经被缓存到Redis里了 刷新小程序清理一下idea的控制台 再次点击访问“蜀味牛蛙” 服务端控制台里没有输出SQL语句说明没有执行SQL是从Redis里查询的缓存 二、SpringCache 1. 介绍 在企业开发中缓存对于提升程序性能有非常大的作用所以已经广泛应用于企业项目开发中。但是缓存技术是多种多样的例如Redis、Caffeine、MemCache、EhCache等等。而不同的缓存技术其操作方法并不统一这就对于开发人员使用缓存造成了一些障碍。 从Spring3.1版本开始Spring就利用AOP思想对不同的缓存技术做了再封装实现了基于注解的缓存功能只需要简单地加一个注解就能实现缓存功能。让开发人员只专注于业务不需要再关心具体的缓存技术。 2. 使用语法 1 起步依赖 起步依赖 dependency     groupIdorg.springframework.boot/groupId     artifactIdspring-boot-starter-cache/artifactId                                                               version2.7.3/version  /dependency 如果只添加上述一个依赖的话springCache默认将会使用ConcurrentHashMap作为缓存容器。但是Spring Cache 其实提供了一层抽象底层可以切换不同的缓存实现例如 EHCache如果添加了EHCache的依赖坐标SpringCache将会使用EhCache作为缓存容器 Caffeine如果添加了caffeine的依赖坐标SpringCache将会使用Caffeine作为缓存容器 Redis(常用)如果添加了Redis依赖坐标SpringCache将会使用Redis作为缓存容器 所以实际开发中通常是添加两个坐标 !-- SpringCache起步依赖坐标 -- dependency     groupIdorg.springframework.boot/groupId     artifactIdspring-boot-starter-cache/artifactId                                                           /dependency !-- Redis起步依赖坐标 -- dependency     groupIdorg.springframework.boot/groupId     artifactIdspring-boot-starter-data-redis/artifactId /dependency 2 使用要求 SpringCache结合Redis时默认会使用JDK序列化方式将数据序列化成字节数组再缓存起来。 我们用的就是这种方式所以我们的实体类要实现Serializable接口 3 常用注解 在SpringCache中提供了很多缓存操作的注解常见的是以下的几个 在spring boot项目中使用缓存技术只需在项目中导入相关缓存技术的依赖包并在启动类上使用EnableCaching开启缓存支持即可。 例如使用Redis作为缓存技术只需要导入Spring data Redis的maven坐标即可。 4 SpEL表达式(了解备用) Spring Cache提供了一些供我们使用的SpEL上下文数据下表直接摘自Spring官方文档 注意 使用方法参数时可以直接写成#参数名也可以写成#p参数索引例如#p0表示索引0的参数 5 步骤小结 先添加依赖坐标 修改引导类加注解EnableCaching开启缓存功能 哪个方法查询数据时想要优先查缓存就在方法上加注解Cacheable 哪个方法执行后想要更新缓存的数据就在方法上加注解CachePut 哪个方法执行后想要清理缓存的数据就在方法上加注解CacheEvict 3.入门案例 1 准备环境 导入基础工程:底层已使用Redis缓存实现 基础环境的代码在我们今天的资料中已经准备好了 大家只需要将这个工程导入进来就可以了 数据库准备: CREATE DATABASE spring_cache_demo; use database spring_cache_demo; create table user (     id   bigint auto_increment primary key,     name varchar(45) null,     age  int         null ); 2 使用入门 1 引导类上加EnableCaching 引导类上加EnableCaching: package com.itheima;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching;EnableCaching //开启声明式缓存功能 SpringBootApplication public class CacheDemoApplication {public static void main(String[] args) {SpringApplication.run(CacheDemoApplication.class, args);} } 2 更新缓存加CachePut CachePut 说明 作用将方法返回值放入缓存更新缓存 用法CachePut(cacheNames, key) 缓存的keySpring将使用 cacheNames的值::key的值作为缓存的key 缓存的值Spring将方法的返回值作为缓存的value 注意注解里的key支持SpringEL表达式 使用示例 如果在做新增操作或者修改操作时可以更新缓存当新增或修改操作后希望把最新的数据缓存起来方便后续使用。可以在新增或修改方法上加注解CachePut /*** 新增用户方法* 注解CachePut将会把方法返回值缓存起来以cacheNameskey作为缓存的key以方法返回值作为缓存的value*/ Override CachePut(cacheNames user, key #user.id) public User addUser(User user) {userMapper.insert(user);return user; } 说明key的写法如下 #user.id : #user指的是方法形参的名称, id指的是user的id属性 , 也就是使用user的id属性作为key ; #result.id : #result代表方法返回值该表达式 代表以返回对象的id属性作为key #p0.id#p0指的是方法中的第一个参数id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ; #a0.id#a0指的是方法中的第一个参数id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ; #root.args[0].id:#root.args[0]指的是方法中的第一个参数id指的是第一个参数的id属性,也就是使用第一个参数 的id属性作为key ; package com.itheima;import com.itheima.entity.User; import com.itheima.service.UserService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;SpringBootTest public class CacheTest {Autowiredprivate UserService userService;Testpublic void testCachePut(){User user new User();user.setName(pony);user.setAge(60);//新增完成后数据库里会多一条数据使用AnotherRedisDesktopManager连接Redis会发现也有此用户的缓存userService.addUser(user);} } 3 使用缓存加Cacheable Cacheable 说明: 作用在方法执行前spring先查看缓存中是否有数据如果有数据则直接返回缓存数据 若没有数据调用方法并将方法返回值放到缓存中 用法Cacheable(cacheNames, key) 缓存的key以cacheNames::key的值作为key查找对应的值 注意注解里的key支持SpringEL表达式 使用示例 在getById上加注解Cacheable /*** 根据id查询用户* Spring会优先从缓存中查找以cacheNames::key作为key查找对应的值* 如果找到了就会直接返回结果这个方法是不会执行的* 如果找不到才会执行这个方法并把方法的返回值缓存起来*/ Override Cacheable(cacheNames user, key #id) public User queryById(Long id) {System.out.println(UserServiceImpl.queryById方法执行了);return userMapper.selectById(id); } 测试效果 打开Another Redis Desktop Manager先把用户1的缓存清除掉 然后在测试类里增加测试方法并执行 Test public void testCacheable(){System.out.println(--------第一次查询用户1没有缓存会执行目标方法查询数据库);System.out.println(userService.queryById(1L));System.out.println(--------第二次查询用户1有缓存了直接取缓存数据不会执行这个方法);System.out.println(userService.queryById(1L));System.out.println(--------第三次查询用户1有缓存了直接取缓存数据不会执行这个方法);System.out.println(userService.queryById(1L)); } 4 清理缓存加CacheEvict CacheEvict 说明 作用清理指定缓存 用法 用法1CacheEvict(cacheNames, key)清除cacheNames::key对应的缓存 用法2CacheEvict(cacheNames, allEntriestrue)清理所有以cacheNames::开头的key对应的缓存 注意注解里的key支持SpringEL表达式 使用示例 Override CacheEvict(cacheNames user, key #id) public void deleteUser(Long id) {System.out.println(UserServiceImpl.deleteUser方法执行了);userMapper.deleteById(id); } 在测试类里增加方法并执行 Override CacheEvict(cacheNames user, key #id) public void deleteUser(Long id) {System.out.println(UserServiceImpl.deleteUser方法执行了);userMapper.deleteById(id); } 4. 使用小结 添加依赖坐标 修改引导类加EnableCaching 方法上加注解 查询方法时优先查询缓存在方法上加Cacheable(cacheNames, key) Spring优先找缓存的数据以cacheNames::key 作为键去查找缓存 如果找到缓存就直接返回结果被调用的这个方法是不执行的 如果没有缓存Spring会调用执行这个方法把方法的返回值 序列化成字节数组然后缓存起来。 调用一个方法时想要更新缓存数据在方法上加CachePut(cacheNames, key) Spring会先调用方法然后把方法的返回值序列化成字节数组 以cacheNames::key作为键以返回值的序列化结果 作为值缓存起来 调用一个方法时想要清理缓存数据 在方法上加CacheEvict(cacheNames, key) Spring会先调用方法再以cacheNames::key为键清理掉对应的缓存 在方法上加CacheEvict(cacheNames, allEntriestrue) Spring会先调用方法再删除所有 以cacheNames开头的key 三、缓存套餐 1 问题说明 同缓存菜品一样我们希望将菜品也缓存到Redis里。这样如果客户端C端访问量大了直接从Redis里读取缓存数据从而减轻数据库的压力。 2 实现思路 实现步骤 1). 导入Spring Cache和Redis相关maven坐标 2). 在启动类上加入EnableCaching注解开启缓存注解功能 3). 在SetmealServiceImpl的查询套餐(用户端)方法上加入Cacheable注解 4). 在SetmealServiceImpl的 新增套餐、删除套餐、修改套餐、起用套餐 等管理端方法上加入CacheEvict注解 3 代码开发 1 添加依赖坐标 修改sky-server的pom.xml文件添加依赖坐标已添加过了不要重复添加 dependency       groupIdorg.springframework.boot/groupId       artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency       groupIdorg.springframework.boot/groupId       artifactIdspring-boot-starter-cache/artifactId /dependency 2 修改引导类加EnableCaching 在启动类上加入EnableCaching注解开启缓存注解功能 package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.transaction.annotation.EnableTransactionManagement;SpringBootApplication EnableTransactionManagement //开启注解方式的事务管理 Slf4j EnableCaching public class SkyApplication {public static void main(String[] args) {SpringApplication.run(SkyApplication.class, args);log.info(server started);} } 3 修改SetmealServiceImpl 浏览套餐时使用缓存 修改list方法增加注解Cacheable Override Cacheable(cacheNames setmeal, key #categoryId) public ListSetmeal list(Integer categoryId) {return setmealMapper.selectEnableListByCategoryId(categoryId); } 套餐变更时清理缓存 4 功能测试 通过前后端联调方式来进行测试同时观察redis中缓存的套餐数据。和缓存菜品功能测试基本一致不再赘述。 四、添加购物车 1. 需求分析和设计 1 产品原型 用户可以将菜品或者套餐添加到购物车。对于菜品来说如果设置了口味信息则需要选择规格后才能加入购物车;对于套餐来说可以直接点击 将当前套餐加入购物车。在购物车中可以修改菜品和套餐的数量也可以清空购物车。 2 接口设计 通过上述原型图设计出对应的添加购物车接口。 说明添加购物车时有可能添加菜品也有可能添加套餐。故传入参数要么是菜品id要么是套餐id。 3 表设计 用户的购物车数据也是需要保存在数据库中的购物车对应的数据表为shopping_cart表具体表结构如下 说明 购物车数据是关联用户的在表结构中我们需要记录每一个用户的购物车数据是哪些 菜品列表展示出来的既有套餐又有菜品如果用户选择的是套餐就保存套餐ID(setmeal_id)如果用户选择的是菜品就保存菜品ID(dish_id) 对同一个菜品/套餐如果选择多份不需要添加多条记录增加数量number即可 2. 代码开发 1 DTO设计 根据添加购物车接口的参数设计DTO 在sky-pojo模块ShoppingCartDTO.java已定义 package com.sky.dto;import lombok.Data; import java.io.Serializable;Data public class ShoppingCartDTO implements Serializable {private Long dishId;private Long setmealId;private String dishFlavor;} 2 ShoppingCartController 创建 ShoppingCartController类 package com.sky.controller.user;import com.sky.dto.ShoppingCartDTO; import com.sky.result.Result; import com.sky.service.ShoppingCartService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;RestController Api(tags 购物车相关接口-C端) RequestMapping(/user/shoppingCart) public class ShoppingCartController {Autowiredprivate ShoppingCartService cartService;PostMapping(/add)ApiOperation(添加购物车)public Result addCart(RequestBody ShoppingCartDTO dto){return cartService.addCart(dto);} } 3 ShoppingCartService 创建ShoppingCartService接口 package com.sky.service;import com.sky.dto.ShoppingCartDTO; import com.sky.entity.ShoppingCart; import com.sky.result.Result;public interface ShoppingCartService {/*** 添加购物车* param dto* return*/Result addCart(ShoppingCartDTO dto); } 4 ShoppingCartServiceImpl 创建ShoppingCartServiceImpl实现类 package com.sky.service.impl;import com.sky.context.BaseContext; import com.sky.dto.ShoppingCartDTO; import com.sky.entity.Dish; import com.sky.entity.Setmeal; import com.sky.entity.ShoppingCart; import com.sky.mapper.DishMapper; import com.sky.mapper.SetmealMapper; import com.sky.mapper.ShoppingCartMapper; import com.sky.result.Result; import com.sky.service.ShoppingCartService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.time.LocalDateTime; import java.util.List;Service public class ShoppingCartServiceImpl implements ShoppingCartService {Autowiredprivate ShoppingCartMapper shoppingCartMapper;Autowiredprivate DishMapper dishMapper;Autowiredprivate SetmealMapper setmealMapper;Overridepublic Result addCart(ShoppingCartDTO dto) {//查询当前商品是否在购物一中Long currentUser BaseContext.getCurrentId();ShoppingCart cart shoppingCartMapper.selectOne(dto, currentUser);if (cart null) {//不在购物车中要新增到购物车里。准备一个entity对象cart new ShoppingCart();BeanUtils.copyProperties(dto, cart);cart.setUserId(currentUser);cart.setCreateTime(LocalDateTime.now());cart.setNumber(1);//还需要判断添加的是套餐还是菜品补全不同的数据if (dto.getDishId() ! null) {//添加的是菜品查询菜品信息Dish dish dishMapper.selectById(dto.getDishId());cart.setName(dish.getName());cart.setImage(dish.getImage());cart.setAmount(dish.getPrice());}else{//添加的是套餐查询套餐信息Setmeal setmeal setmealMapper.selectById(dto.getSetmealId());cart.setName(setmeal.getName());cart.setImage(setmeal.getImage());cart.setAmount(setmeal.getPrice());}//保存到数据库里shoppingCartMapper.insert(cart);}else{//在购物车中要修改购物车中商品的数量1shoppingCartMapper.updateNumber(cart.getId(), 1);}return Result.success();} } 5 ShoppingCartMapper 创建SShoppingCartMapper接口: package com.sky.mapper;import com.sky.dto.ShoppingCartDTO; import com.sky.entity.ShoppingCart; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Update;Mapper public interface ShoppingCartMapper {ShoppingCart selectOne(ShoppingCartDTO dto, Long userId);Update(update shopping_cart set number number #{increment} where id #{id})void updateNumber(Long id, int increment);Insert(insert into shopping_cart (name, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time) values (#{name}, #{image}, #{userId}, #{dishId}, #{setmealId}, #{dishFlavor}, #{number}, #{amount}, #{createTime}))void insert(ShoppingCart cart); } 6 ShoppingCartMapper.xml 创建ShoppingCartMapper.xml ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.sky.mapper.ShoppingCartMapperselect idselectOne resultTypecom.sky.entity.ShoppingCartselect * from shopping_cartwhereif testuserId!nulland user_id #{userId}/ifif testdto.dishId!nulland dish_id #{dto.dishId}/ifif testdto.setmealId!nulland setmeal_id #{dto.setmealId}/ifif testdto.dishFlavor!null and dto.dishFlavor.length()0and dish_flavor #{dto.dishFlavor}/if/where/select /mapper 3. 功能测试 进入小程序添加菜品 五、查看购物车 1. 需求分析和设计 1 产品原型 当用户添加完菜品和套餐后可进入到购物车中查看购物中的菜品和套餐。 2 接口设计 2. 代码开发 1 ShoppingCartController 在ShoppingCartController中创建查看购物车的方法 GetMapping(/list) ApiOperation(查看购物车) public Result queryCart(){return cartService.queryCart(); } 2 ShoppingCartService 在ShoppingCartService接口中声明查看购物车的方法 /*** 查询当前用户的购物车* return*/Result queryCart(); 3 ShoppingCartServiceImpl 在ShoppingCartServiceImpl中实现查看购物车的方法 Overridepublic Result queryCart() {Long currentUser BaseContext.getCurrentId();ListShoppingCart cartList shoppingCartMapper.selectListByUser(currentUser);return Result.success(cartList);} 4 ShoppingCartMapper Select(select * from shopping_cart where user_id #{userId}) ListShoppingCart selectListByUser(Long userId); 3. 功能测试 当进入小程序时就会发起查看购物车的请求 六、清空购物车 1. 需求分析和设计 1 产品原型 当点击清空按钮时会把购物车中的数据全部清空。 2 接口设计 2. 代码开发 1 ShoppingCartController 在ShoppingCartController中创建清空购物车的方法 DeleteMapping(/clean) ApiOperation(清空购物车) public Result cleanCart(){return cartService.cleanCart(); } 2 ShoppingCartService 在ShoppingCartService接口中声明清空购物车的方法 /*** 清空购物车* return*/Result cleanCart(); 3 ShoppingCartServiceImpl 在ShoppingCartServiceImpl中实现清空购物车的方法 Override public Result cleanCart() {shoppingCartMapper.deleteByUser(BaseContext.getCurrentId());return Result.success(); } 4 ShoppingCartMapper 在ShoppingCartMapper接口中创建删除购物车数据的方法 Delete(delete from shopping_cart where user_id #{userId}) void deleteByUser(Long userId); 3. 功能测试 进入到购物车页面 点击清空 七、删除购物车中一个商品 //controllerPostMapping(/sub)ApiOperation(删除购物车中一个商品)public Result deleteOne(RequestBody ShoppingCartDTO dto){return cartService.deleteOne(dto); }----------------- //ShoppingCartServiceResult deleteOne(ShoppingCartDTO dto);----------------- //ShoppingCartServiceImplOverridepublic Result deleteOne(ShoppingCartDTO dto) {Long currentUser BaseContext.getCurrentId();ShoppingCart cart shoppingCartMapper.selectOne(dto, currentUser);if (cart.getNumber()1){shoppingCartMapper.deleteById(cart.getId());}shoppingCartMapper.updateNumber(cart.getId(), -1);return Result.success(); }------------------- //mapper ShoppingCart selectOne(ShoppingCartDTO dto, Long userId);Update(update shopping_cart set numbernumber#{increment} where id#{id})void updateNumber(Long id, int increment);------------ //XML ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.sky.mapper.ShoppingCartMapperselect idselectOne resultTypecom.sky.entity.ShoppingCartselect * from shopping_cartwhereif testuserId!nulland user_id #{userId}/ifif testdto.dishId!nulland dish_id #{dto.dishId}/ifif testdto.setmealId!nulland setmeal_id #{dto.setmealId}/ifif testdto.dishFlavor!null and dto.dishFlavor.length()0and dish_flavor #{dto.dishFlavor}/if/where/select /mapper
http://www.dnsts.com.cn/news/147749.html

相关文章:

  • 赣州网站建设中心北京软件开发哪家好
  • 海东企业网站建设公司跨境电商网络营销是什么
  • 网站首页不见怎么做乌克兰最新消息今天
  • 山东住房建设部网站wordpress主题xueui
  • 个人网站二级域名做淘宝客网站建设服务器是什么意思
  • 兴义做网站建站合同模板
  • 电商学院建设设计网站网站风格的设计
  • 做电子书的网站很有名后来被关闭了烟台网站建设询问企汇互联专业
  • 非凡免费建网站平台下载个网上销售网站
  • 蓟县网站建设公司wordpress产品系统
  • 网站被攻击如何处理wordpress内页打不开
  • 网站建设自主建设falsh网站模板下载
  • 个人微信网站建设购物网站策划方案
  • 邢台做网站推广价格网站制作的内容什么好
  • 个人 网站建设wordpress纯笔记主题
  • 网站后端技术语言个人做网站开发
  • 公司网站备案需要什么开发公司起名大全
  • 微信小程序开发和网站开发的区别展台设计公司
  • 影视网站建设多少钱佛山产品设计公司
  • 网站开发验收模板做网站什么时候注册商标
  • 下列哪个网站不属于sns(社交网络)u盘启动盘制作工具
  • 医疗器械网站建设策划书电子商城网站的设计与实现
  • 食品行业网站源码昆明网站建设的公司
  • 职校网站模板网站开发与网站设计区别
  • 泰州做网站淘宝做一个电影网站需要多少钱
  • 增城网站怎么做seo常营网站建设
  • 自助网站建设 网易沈阳h5网站建设
  • 网站规划与建设课程来宾建设网站
  • 网站规划的类型怎么做网上卖货
  • 网站管理怎么做百度免费推广网站