资料下载:
https://gitee.com/a-fish-v/sky-take-out
day1:
1. 初始环境导入
先创建一个主文件夹xxx,放到非中文目录下,
从提供的资料中,找到管理端的前端工程文件夹,将这个文件夹导入到你创建的主文件夹中
双击nginx.exe启动前端工程,再将后端的初始工程文件夹导入到你创建的这个主文件夹中,
2. 运行项目
双击nginx.exe启动前端工程,在idea中打开后端的初始工程文件夹,jdk版本可以设置成17,防止出现jdk版本过低的警告。
在sky-take-out主模块下会有三个子模块
分别是sky-common(存放一些工具类) ; sky-pojo(实体类, DTO, VO) ; sky-server(配置类, Controller, Mapper, Service), 在里面找到项目的启动类SkyApplication, 点击运行,然后访问
http://localhost:80, 初始密码是123456,然后就点击登录进入到管理端
3. 创建数据库
然后在资料中找到sky.sql文件,执行sql的话,你可选择sqlyang或者DataGrip,也可以idea内置的(前提是你装了mysql),然后执行一次就可以,
一共有11张表,像employee【员工表】category【分类表】dish【菜品表】dish_flavor【菜品口味表】setmeal【套餐表】... 都是管理端的数据库表
管理端登录模块
就是管理员登录一次后生成JWT令牌,返回给前端 ,然后每次登录时, 携带这个码跟后端进行校验,来判断登录成功或失败
login方法中 生成令牌, 返回给前端
生成Jwt令牌:jwt - > 签名算法+密钥+自定义内容+有效期
解析 - > 密钥
jwt 的 自定义内容【clamis对象, 必须是Map类型】中包含了当前登录的员工信息
表现层(Controller)
/**
* 登录
*
* @param employeeLoginDTO
* @return
*/
@PostMapping("/login")
@ApiOperation(value = "员工登录")
public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {
log.info("员工登录:{}", employeeLoginDTO);
Employee employee = employeeService.login(employeeLoginDTO);
//登录成功后,生成jwt令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.EMP_ID, employee.getId());
String token = JwtUtil.createJWT(
jwtProperties.getAdminSecretKey(),
jwtProperties.getAdminTtl(),
claims);
EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()
.id(employee.getId())
.userName(employee.getUsername())
.name(employee.getName())
.token(token)
.build();
return Result.success(employeeLoginVO);
}
JwtUtil工具类
createJWT方法中指定了 密钥+有效期+自定义内容
parseJWT 方法中指定了 密钥 和 生成的token , 都是固定写法
public class JwtUtil {
/**
* 生成jwt
* 使用Hs256算法, 私匙使用固定秘钥
*
* @param secretKey jwt秘钥
* @param ttlMillis jwt过期时间(毫秒)
* @param claims 设置的信息
* @return
*/
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
// 指定签名的时候使用的签名算法,也就是header那部分
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 生成JWT的时间
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
// 设置jwt的body
JwtBuilder builder = Jwts.builder()
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
.setClaims(claims)
// 设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
// 设置过期时间
.setExpiration(exp);
return builder.compact();
}
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @param token 加密后的token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
// 设置需要解析的jwt, .getBody()方法可以得到jwt中的第二个部分[自定义部分]
.parseClaimsJws(token).getBody();
return claims;
}
}
@Component
//指定从配置文件中加载以sky.jwt开头的属性
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {
/**
* 管理端员工生成jwt令牌相关配置
*/
private String adminSecretKey;
private long adminTtl;
private String adminTokenName;
/**
* 用户端微信用户生成jwt令牌相关配置
*/
private String userSecretKey;
private long userTtl;
private String userTokenName;
}
yml文件中密钥,有效期.....
sky:
jwt:
# 设置jwt签名加密时使用的秘钥
admin-secret-key: itcast
# 设置jwt过期时间
admin-ttl: 7200000
# 设置前端传递过来的令牌名称
admin-token-name: token
user-secret-key: itheima
user-ttl: 7200000
user-token-name: authentication
表现层调用 Employee employee = employeeService.login(employeeLoginDTO);
public Employee login(EmployeeLoginDTO employeeLoginDTO) {
String username = employeeLoginDTO.getUsername();
String password = employeeLoginDTO.getPassword();
//1、根据用户名查询数据库中的数据
Employee employee = employeeMapper.getByUsername(username);
//2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)
if (employee == null) {
//账号不存在, 下面所有的异常都继承自 BaseException 方法, 由全局异常处理器
//GlobalExceptionHandler 统一进行处理
throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
}
//密码比对
//对前端传过来的明文密码进行md5加密处理
password = DigestUtils.md5DigestAsHex(password.getBytes());
if (!password.equals(employee.getPassword())) {
//密码错误
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
// StatusConstant.DISABLE = 0
if (employee.getStatus() == StatusConstant.DISABLE) {
//账号被锁定
throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
}
//3、返回实体对象
return employee;
}
调用Mapper 层的接口Employee employee = employeeMapper.getByUsername(username);
查询员工表
nginx反向代理
进到nginx-1.20.2\conf,打开nginx配置
# 反向代理,处理管理端发送的请求
location /api/ {
proxy_pass http://localhost:8080/admin/;
#proxy_pass http://webservers/admin/;
}
当在访问http://localhost/api/employee/login,nginx接收到请求后转到http://localhost:8080/admin/,故最终的请求地址为http://localhost:8080/admin/employee/login,和后台服务的访问地址一致。
对登录密码进行MD5加密
将MD5加密后的密码更新到数据库employee表中
password = DigestUtils.md5DigestAsHex(password.getBytes());
使用DigestUtils这个工具类
代码逻辑就是将password加密后的和数据库employee表中的进行对比
Swagger【后端【表现层】接口测试, 类似于potman】
1. 导入 knife4j 的maven坐标, 在pom.xml中添加依赖
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
2. 在配置类WebMvcConfiguration中加入 knife4j 相关配置
/**
* 通过knife4j生成接口文档
* @return
*/
@Bean
public Docket docket() {
ApiInfo apiInfo = new ApiInfoBuilder()
// 指定文档的标题, 版本, 描述
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.select()
// 可自定义:扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
// 所有路径[路径过滤]
.paths(PathSelectors.any())
.build();
return docket;
}
3. 静态资源过滤【ssm里面提到的addResourceHandlers】
在配置类WebMvcConfiguration中添加
/**
* 设置静态资源映射
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
// 添加静态资源的访问路径 /webjars/** 中的两个星号 ** 表示匹配 /webjars/ 目录下的所有文件和子目录
使用 http://localhost:8080/doc.html 访问
上面很多都是资料中提供好的
day2:
新增员工
员工分页查询
启用禁用员工账号
编辑员工
导入分类模块功能代码
1. 新增员工
根据产品原型分析/资料中的接口文档, 员工id , 账号, 姓名, 手机号, 性别, 身份证号, 将这些字段封装成一个DTO类由管理端提交到服务端
@Data
public class EmployeeDTO implements Serializable {
private Long id;
private String username;
private String name;
private String phone;
private String sex;
private String idNumber;
}
进入到sky-server模块中,在com.sky.controller.admin包下,在EmployeeController中创建新增员工方法,接收前端提交的参数
@PostMapping
@ApiOperation(value = "新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
log.info("新增员工:{}", employeeDTO);
employeeService.save(employeeDTO);
return Result.success();
}
Result<T> 类 是返回给管理端的json数据,其中包含code, msg, data
Result.success(); 操作成功, 返回状态码:1成功
/**
* 后端统一返回结果
* @param <T>
*/
@Data
public class Result<T> implements Serializable {
private Integer code; //编码:1成功,0和其它数字为失败
private String msg; //错误信息
private T data; //数据
// 用于操作成功但不需要返回数据的场景
public static <T> Result<T> success() {
Result<T> result = new Result<T>();
result.code = 1;
return result;
}
// 用于操作成功且需要返回数据的场景。
public static <T> Result<T> success(T object) {
Result<T> result = new Result<T>();
result.data = object;
result.code = 1;
return result;
}
// 用于操作失败的场景,设置错误信息。
public static <T> Result<T> error(String msg) {
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
}
进入到sky-server模块中,com.sky.server.EmployeeService
在service业务层定义接口, 然后在serviceImp写具体的业务代码
public interface EmployeeService {
/**
* 员工登录
* @param employeeLoginDTO
* @return
*/
Employee login(EmployeeLoginDTO employeeLoginDTO);
void save(EmployeeDTO employeeDTO);
}
在serviceImp 包中实现刚定义的save接口
你可以对比employee实体类和employeeDTO,完善DTO中缺失的属性,调用Mapper层接口中的方法【记得要在当前类的上面声明employeeMapper对象】,
//新增员工
public void save(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
// 将EmployeeDTO(属性少)对象转换为Employee对象(属性多)
// 对象属性拷贝
BeanUtils.copyProperties(employeeDTO, employee);
// 设置账号的状态, 默认正常状态 1表示正常 0 表示禁用
employee.setStatus(StatusConstant.ENABLE);
// 设置密码, 默认为123456
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
// 设置当前记录的创建时间和修改时间
// employee.setCreateTime(LocalDateTime.now());
// employee.setUpdateTime(LocalDateTime.now());
// 设置当前记录创建人id和修改人id
// TODO 后期需要修改为登录用户的id
// employee.setCreateUser(BaseContext.getCurrentId());
// employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.insert(employee);
}
employeeMapper.insert(employee);
// 插入员工数据
@Insert("insert into employee(name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user, status) " +
"values(#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser} ,#{status})")
@AutoFill(value = OperationType.INSERT)
void insert(Employee employee);
employee实体类中的属性和数据库字段不同的情况
在application.yml中已开启驼峰命名,故id_number和idNumber可对应
注:在初始学mybatis时, 使用的是.xml文件进行配置, 但是spring-boot中做出了改变
mybatis:
configuration:
#开启驼峰命名
map-underscore-to-camel-case: true
在swagger中测试这个接口
调用员工登录接口获得一个合法的JWT令牌,【初次登录会返回给管理端的令牌】
添加令牌:
将合法的JWT令牌添加到全局参数中
文档管理-->全局参数设置-->添加参数
否则会报错
2. 员工分页查询
系统中的员工很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。而在我们的分页查询页面中, 除了分页条件以外,还有一个查询条件 "员工姓名"。
根据接口文档/原型图,请求参数有name, page【页码】pageSize 【每页记录数】
请求参数类型为Query,不是json格式提交,在路径后直接拼接。/admin/employee/page?name=zhangsan
返回数据中records数组中使用Employee实体类对属性进行封装。
@Data
public class EmployeePageQueryDTO implements Serializable {
//员工姓名
private String name;
//页码
private int page;
//每页显示记录数
private int pageSize;
}
后面所有的分页查询,统一都封装为PageResult对象【返回给管理端中的 data】
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
private long total; //总记录数
private List records; //当前页数据集合, employee数组
}
员工信息分页查询后端返回的对象类型为: Result<PageResult>
查询成功:
data: PageResult
code : 1
在sky-server模块中,com.sky.controller.admin.EmployeeController中添加分页查询方法。
//员工分页查询
@GetMapping("/page")
@ApiOperation(value = "员工分页查询")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
log.info("员工分页查询:{}", employeePageQueryDTO);
PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);
return Result.success(pageResult);
}
在EmployeeService接口中声明pageQuery方法:
public interface EmployeeService {
/**
* 员工登录
* @param employeeLoginDTO
* @return
*/
Employee login(EmployeeLoginDTO employeeLoginDTO);
void save(EmployeeDTO employeeDTO);
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
}
在EmployeeServiceImpl中实现pageQuery方法:
注:此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发。底层基于 mybatis 的拦截器实现。
故在pom.xml文中添加依赖(初始工程已添加)
// 员工分页查询
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO){
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
/*
PageHelper:MyBatis分页插件
startPage():设置分页参数,后续的第一个MyBatis查询会自动分页
getPage():当前页码
getPageSize():每页记录数
*/
Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);
/*
调用Mapper层的分页查询方法
返回Page<Employee>对象(PageHelper提供的分页对象)
这个查询会自动应用前面设置的分页参数
*/
long total = page.getTotal(); // 总记录数
List<Employee> result = page.getResult(); // 当前页的数据列表
return new PageResult(total,result); // 将数据封装到自定义的PageResult对象中
}
在 EmployeeMapper 中声明 pageQuery 方法:
// 分页查询 -> 不再使用注解, 而采用动态的sql
Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.EmployeeMapper">
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name!= null and name!= ''">
and name like concat('%', #{name}, '%')
</if>
</where>
order by create_time desc
</select>
</mapper>
// spring-boot, xml文件中的几个常见属性 namespace: 和你mapper层的对应接口进行绑定
// id:指定接口中对象的方法名 resultType : 你查询的数据的类型
时间格式问题:可以在每个时间属性上添加@JsonFormat指定日期格式
也可以
在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理
就是配置类WebMvcConfiguration 继承 WebMvcConfigurationSupport类,然后重写WebMvcConfigurationSupport类中的extendMessageConverters方法, 方法形参都是固定的
/**
* 扩展Spring MVC框架的消息转化器
* @param converters
*/
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器...");
//创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
// 用自定义的JacksonObjectMapper替换默认的ObjectMapper
converter.setObjectMapper(new JacksonObjectMapper());
//将自己的消息转化器加入容器中
// add(0, converter):插入到列表的第一个位置(最高优先级)
//Spring会按顺序使用第一个能够处理当前类型的转换器
converters.add(0,converter);
}
时间格式定义,sky-common模块中
package com.sky.json;
public class JacksonObjectMapper extends ObjectMapper {
//.......
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
//.......
}
}
3. 启用禁用员工账号
在员工管理列表页面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统,启用后的员工可以正常登录。如果某个员工账号状态为正常,则按钮显示为 "禁用",如果员工账号状态为已禁用,则按钮显示为"启用"。
1). 路径参数携带状态值。
2). 同时,把id传递过去,明确对哪个用户进行操作。
3). 返回数据code状态是必须,其它是非必须。
在url中进行拼接status和员工id,分别填充到EmployeeController的形参中
在sky-server模块中,根据接口设计中的请求参数形式对应的在 EmployeeController 中创建启用禁用员工账号的方法:
@PostMapping("/status/{status}")
@ApiOperation(value = "启用禁用员工账号")
public Result startOrStop(@PathVariable Integer status, Long id){
log.info("启用禁用员工账号:{},{}",status,id);
employeeService.startOrStop(status, id);
return Result.success();
}
在 EmployeeService 接口中声明启用禁用员工账号的业务方法:
public interface EmployeeService {
/**
* 员工登录
* @param employeeLoginDTO
* @return
*/
Employee login(EmployeeLoginDTO employeeLoginDTO);
void save(EmployeeDTO employeeDTO);
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
void startOrStop(Integer status, Long id);
}
在 EmployeeServiceImpl 中实现启用禁用员工账号的业务方法:
//启用禁用员工账号
public void startOrStop(Integer status, Long id) {
// 还是类似于写一个sql : update employee set status = ? where id = ?
// 扩展这个方法
Employee employee = Employee.builder().status(status).id(id).build();
employeeMapper.update(employee);
}
在 EmployeeMapper 接口中声明 update 方法:
@AutoFill(value = OperationType.UPDATE)
void update(Employee employee);
在 EmployeeMapper.xml 中编写SQL:
<update id="update" parameterType="Employee">
update employee
<set>
<if test="name != null">name = #{name},</if>
<if test="username != null">username = #{username},</if>
<if test="password != null">password = #{password},</if>
<if test="phone != null">phone = #{phone},</if>
<if test="sex != null">sex = #{sex},</if>
<if test="idNumber != null">id_Number = #{idNumber},</if>
<if test="updateTime != null">update_Time = #{updateTime},</if>
<if test="updateUser != null">update_User = #{updateUser},</if>
<if test="status != null">status = #{status},</if>
</set>
where id = #{id}
</update>
4. 编辑员工
在员工管理列表页面点击 "编辑" 按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击 "保存" 按钮完成编辑操作。
设计两个接口:
1. 根据id就进行回显员工信息 ----> 路径参数,请求方式对应rest风格中的GET
2. 对回显的员工信息进行修改 ----> 提交json数据到后台 ,请求方式对应rest风格中的PUT
1. 根据id就进行回显员工信息
在 EmployeeController 中创建 getById 方法:
@GetMapping("/{id}")
@ApiOperation(value = "查询员工信息")
public Result<Employee> getById(@PathVariable Long id){
Employee employee = employeeService.getById(id);
return Result.success(employee);
}
在 EmployeeService 接口中声明 getById 方法:
Employee getById(Long id);
在 EmployeeServiceImpl 中实现 getById 方法:
//根据id查询员工信息
@Override
public Employee getById(Long id) {
Employee employee = employeeMapper.getById(id);
employee.setPassword("******");
return employee;
}
在 EmployeeMapper 接口中声明 getById 方法:
// 根据id查询员工信息
@Select("select * from employee where id = #{id}")
Employee getById(Long id);
2. 对回显的员工信息进行修改
在 EmployeeController 中创建 update 方法:
//更新/修改员工信息
@PutMapping
@ApiOperation(value = "更新员工信息")
public Result update(@RequestBody EmployeeDTO employeeDTO){
log.info("更新员工信息:{}", employeeDTO);
employeeService.update(employeeDTO);
return Result.success();
}
在 EmployeeService 接口中声明 update 方法:
public interface EmployeeService {
/**
* 员工登录
* @param employeeLoginDTO
* @return
*/
Employee login(EmployeeLoginDTO employeeLoginDTO);
void save(EmployeeDTO employeeDTO);
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
void startOrStop(Integer status, Long id);
Employee getById(Long id);
void update(EmployeeDTO employeeDTO);
}
在 EmployeeServiceImpl 中实现 update 方法:
// 编辑员工信息
@Override
public void update(EmployeeDTO employeeDTO) {
// 实体属性不等 -> 对象的属性拷贝
Employee employee = new Employee();
BeanUtils.copyProperties(employeeDTO, employee);
// 时间和id
// employee.setUpdateTime(LocalDateTime.now());
//employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.update(employee);
}
在实现启用禁用员工账号功能时,已实现employeeMapper.update(employee),在此不需写Mapper层代码,你业务代码写的再多,最后也肯定是落脚到操作数据库中对应的表。
接口测试和前后端联调
5. 导入分类模块功能代码
后台系统中可以管理分类信息,分类包括两种类型,分别是 菜品分类 和 套餐分类 。
先来分析菜品分类相关功能。
新增菜品分类:当我们在后台系统中添加菜品时需要选择一个菜品分类,在移动端也会按照菜品分类来展示对应的菜品。
菜品分类分页查询:系统中的分类很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
根据id删除菜品分类:在分类管理列表页面,可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除。
修改菜品分类:在分类管理列表页面点击修改按钮,弹出修改窗口,在修改窗口回显分类信息并进行修改,最后点击确定按钮完成修改操作。
启用禁用菜品分类:在分类管理列表页面,可以对某个分类进行启用或者禁用操作。
分类类型查询:当点击分类类型下拉框时,从数据库中查询所有的菜品分类数据进行展示。
和上面员工的接口类似,可能多修改菜品/套餐这个接口
这个模块资料里有可以导入的现成代码
接口文档中提供了下面这6个接口
新增分类
分类分页查询
根据id删除分类
修改分类
启用禁用分类
根据类型查询分类
1. 新增分类
菜品分类和套餐分类共用一个接口, 新增操作携带的参数有name, 排序所需数字, type: 区分共用接口,提供的category表【数据库表】字段比你前端提交过来的DTO字段多,应该还是要用工具类进行拷贝
就是使用Rest风格对表现层进行开发的时候,删除和修改都应该在路径参数中指定id,但是下面代码中写法直接就 @DeleteMapping @PutMapping 接口文档里面把id定义成了query, 这样也可以
2. 分类分页查询
请求方式为GET, query参数为page【页码】,pageSize【每页记录数】前面写过【新增员工】,使用PageHelper插件,具体参数看资料中的接口文档
3. 根据id删除分类
请求方式为DELETE, query参数为id, 返回的VO还是Result封装的
4. 修改分类
请求方式为PUT, query参数为id, name 排序数字,type区分分类类型
5.启用禁用分类
还是路径参数中携带status: 1【启用】,0【禁用】,query参数为id
6. 根据类型查询分类
请求方式为GET, 查询所有相同类型的数据
可按照mapper-->service-->controller依次导入,这样代码不会显示相应的报错。
进入到sky-server模块
DishMapper.java
package com.sky.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface DishMapper {
/**
* 根据分类id查询菜品数量
* @param categoryId
* @return
*/
@Select("select count(id) from dish where category_id = #{categoryId}")
Integer countByCategoryId(Long categoryId);
}
SetmealMapper.java
package com.sky.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface SetmealMapper {
/**
* 根据分类id查询套餐的数量
* @param id
* @return
*/
@Select("select count(id) from setmeal where category_id = #{categoryId}")
Integer countByCategoryId(Long id);
}
CategoryMapper.java
package com.sky.mapper;
import com.github.pagehelper.Page;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
impor
苍穹外卖操作详解

最低0.47元/天 解锁文章
4199

被折叠的 条评论
为什么被折叠?



