苍穹外卖|学习笔记|day06
博主个人背景:双非本211硕 研一下。深知自身水平较差 算法无戏,自学java的求生之路
计划每日学习,完成苍穹外卖的学习。借此博客写明学习遇到的问题以及解决方案,同大家一起交流学习。
导入分类管理功能代码[2025.6.5]
本实现由自己所写,可能同项目提供的参考代码略有出入。建议各位读者自己按照接口文档编写相应的代码,再同项目提供的代码进行比对学习。
1.需求分析【查看产品原型、设计分页接口】
今天向大家推荐一款比较好用的接口管理软件:Apifox【个人认为是比视频推荐的接口管理工具效果更好】

2.代码实现
1.新增分类

Controller:【前端传送过来的数据,往往要进行封装传递,在当前的项目当中都使用DTO结尾的类来进行封装保存数据】
@PostMapping
@ApiOperation("新增分类")
public Result<String> save(@RequestBody CategoryDTO categoryDTO){//记得说明为什么要使用DTO的代码log.info("新增分类的信息为{}", categoryDTO);categoryService.save(categoryDTO);return Result.success();
}
Service:【设置相关参数,优先使用常量!!!】
@Override
public void save(CategoryDTO categoryDTO) {Category category =new Category();//采用属性赋值BeanUtils.copyProperties(categoryDTO,category);//初始化其他属性//默认新增分类处于禁用状态[设置相关参数,优先使用常量!!!]category.setStatus(StatusConstant.DISABLE);category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());//通过JWT获取相关操作者的Id[前面所学]category.setCreateUser(BaseContext.getCurrentId());category.setUpdateUser(BaseContext.getCurrentId());//初始化完成相关参数之后,调用mapper的相关方法.通过底层进行调用底层逻辑的代码。categoryMapper.save(category);}
Mapper:
@Insert("insert into category(type,name,sort,status,create_time,update_time,create_user,update_user)" +"values (#{type},#{name},#{sort},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser}) ")
void save(Category category);
2.根据id删除分类

Controller:
@DeleteMapping
@ApiOperation("根据id删除分类")
public Result<String> delete(Long id){log.info("要删除的分类id是{}",id);categoryService.delete(id);return Result.success();}
Service:
public void delete(Long id) {categoryMapper.delete(id);
}
Mapper:
@Delete("delete from category where id = #{id}")
void delete(Long id);
3.分类分页查询【所有分页查询的方式比较固定,建议自己多写几遍。】

Controller:【注意查看分页查询所返回的数据格式!】
@GetMapping("page")
@ApiOperation("分类分页查询")
public Result<PageResult> page(String name,int page,int pageSize,Integer type){CategoryPageQueryDTO categoryPageQueryDTO =new CategoryPageQueryDTO();categoryPageQueryDTO.setName(name);categoryPageQueryDTO.setPage(page);categoryPageQueryDTO.setPageSize(pageSize);categoryPageQueryDTO.setType(type);log.info("要分类分页查询的相关信息为{}",categoryPageQueryDTO);PageResult pageResult=categoryService.page(categoryPageQueryDTO);return Result.success(pageResult);
}
Service:
public PageResult page(CategoryPageQueryDTO categoryPageQueryDTO) {//此语句等价于 sql当中的limit限制语句PageHelper.startPage(categoryPageQueryDTO.getPage(),categoryPageQueryDTO.getPageSize());//使用分页查询的固定格式,使用Page<T>当作操作的返回类型Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO);Long total = page.getTotal();List<Category> records = page.getResult();return new PageResult(total,records);
}
Mapper:
<select id="pageQuery" resultType="com.sky.entity.Category">select * from category<where><if test="name !=null and name !=''">name = #{name}</if><if test="type != null and type != ''">and type = #{type}</if></where>
</select>
4.根据类型查询分类

Controller:【这里要注意:根据类型查询分类返回的结果肯定不止一个,所以返回类型编写为:List】
@GetMapping("list")
@ApiOperation("根据类型查询分类")
public Result<List<Category>> list(Integer type){log.info("要查询的分类的类型是{}",type);List<Category> categoryList=categoryService.list(type);return Result.success(categoryList);
}
Service:
@Override
public List<Category> list(Integer type) {return categoryMapper.list(type);
}
Mapper:
@Select("select * from category where type = #{type}")
List<Category> list(Integer type);
其余两个接口实现略过,较为简单。
小节遇到的问题/疑问点/难点:[部分参考,侵权删]
1.@RequestMapping(“/admin/category”)注解
(1)标注在方法上
用于方法上,表示在类的父路径下追加方法上注解中的地址将会访问到该方法
(2)标注在类上【常用方式】
用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。[这里我们要访问根据类型查询分类,则访问路径为:/admin/category/list] 【在类的父路径下追加方法的路径】
@RestController
@RequestMapping("/admin/category")
@Slf4j
@Api(tags = "分类相关注解")
public class CategoryController {
/*** 根据类型查询分类* @param type* @return*/@GetMapping("list")@ApiOperation("根据类型查询分类")public Result<List<Category>> list(Integer type){log.info("要查询的分类的类型是{}",type);//这里有一个疑问到底是返回 Category 还是 Category的集合List<Category> categoryList=categoryService.list(type);return Result.success(categoryList);}
}
2.@Api 常用注解**【Swagger 提供的注解】**
(1)@Api:用在请求的类上,表示对类的说明 【用于给类添加说明信息,tags
用于在文档中归类分组显示】
tags=“说明该类的作用,可以在swager接口文档的页面看到相关的解释”
例如:
@RestController
@RequestMapping("/admin/category")
@Slf4j
@Api(tags = "分类相关注解")
public class CategoryController {
}
我们在相关的接口页面可以看到:

(2)@ApiOperation 用在请求的方法上,说明方法的用途、作用
@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response =“接口返回参数类型”, notes = “接口发布说明”;
例如:
@GetMapping("list")
@ApiOperation("根据类型查询分类")
public Result<List<Category>> list(Integer type){log.info("要查询的分类的类型是{}",type);//这里有一个疑问到底是返回 Category 还是 Category的集合List<Category> categoryList=categoryService.list(type);return Result.success(categoryList);
}
我们在相关的接口页面可以看到:

3.@RestController注解
@RestController = @Controller + @ResponseBody
@ResponseBody 注解的作用是将Controller的方法返回的对象,通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
4.新创建文件相关添加注解的说明
(1)Controller:[Java类]
@RestController //@RestController = @Controller + @ResponseBody
@RequestMapping("/admin/category") //用于类上,标记路径
@Slf4j //日志相关的注解
@Api(tags = "分类相关注解") //API相关说明,Swagger 提供的注解,用于给类添加说明信息,`tags` 用于在文档中归类分组显示
public class CategoryController {}
(2)Service: [Java实现类 + Interface方法接口] 【@Service注解是写在Service的实现类当中,而不是写在其接口上面!!!】
@Service
public class CategoryServiceImpl implements CategoryService {}
(3)Mapper:【Interface接口 + xml文件】
要注意简单sql可以直接在Mapper接口类上面通过注解来完成!
@Mapper
public interface CategoryMapper {@Insert("insert into category(type,name,sort,status,create_time,update_time,create_user,update_user)" +"values (#{type},#{name},#{sort},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser}) ")void save(Category category);}
如果是动态sql则需要通过xml文件来完成!
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--*************************输入namespace:mapper对应接口的全限定符 就是写mapper接口的路径[com.mapper.xxx]**********************-->
<mapper namespace="com.sky.mapper.CategoryMapper"><!-- 声明标签写sql语句 select insert update delete一个标签对应接口的一个方法! 方法的一个实现!例如:<select id="" resultType=""></select>id对应接口的方法名【所以Mapper接口方法不能进行重载!】! resultType对应返回类型!
--><select id="pageQuery" resultType="com.sky.entity.Category">select * from category<where><if test="name !=null and name !=''">name = #{name}</if><if test="type != null and type != ''">and type = #{type}</if></where></select></mapper>
5.GET
请求:GET
请求默认是无请求体的,不使用@RequestBody
GET
请求:GET
请求默认是无请求体的,通常是通过 URL 参数传递查询信息(例如,?name=xxx&type=yyy
)。
@RequestBody
:这个注解是用来从请求体中获取数据的,通常用于 POST
、PUT
请求。