今天的学习任务:认识项目的结构,熟悉三层架构,并实践开发员工管理模块的功能:新增员工,员工分页查询,禁用和启用员工和修改员工的功能实现。并导入了分类管理模块,为之后的学习打下基础。
项目结构和前置知识
项目结构
苍穹外卖的后端,用的是maven分模块管理:

不同于tlias这种基础的项目,把各种东西都塞在一个模块中显得庞杂紊乱,苍穹外卖实现的是分模块组织项目:
sky-server:
实现三层架构,程序的主体部分,程序运行和处理业务的主要担当。
sky-pojo:
定义实体类。但是与小型项目所有的实体类定义在一个pojo包下并且功能没有明确区分不同,该包下根据不同实体的职责定义了 三种实体:
DTO:data transport object,负责数据传输的对象。用于执行登录等功能时封装和传输数据。
ENTITY:负责封装各种实体数据的对象,传统意义上的plain old java object。包含比如员工,菜品等实体的数据字段定义。
VO:Value Object ,值对象。展示用的数据。负责给前端展示,让人看到。
sky-common:
定义了一些公共类。常量类,异常类,工具类等。比如JwtUtils负责产生jwt令牌用于登录。
通过模块分层,可以更好的管理项目并明确各个类和功能模块的职责,便于掌握项目结构,利于维护和迭代开发。
网络请求
四种网络请求:get,post,put,delete
重要的是理解post和put功能的区别。
重要的响应码:200,401,500,404
200:响应成功
401:未认证
500:内部服务器错误
404:资源不存在
三层架构
mapper/dao:负责与数据库交互
service:处理数据。接收controller数据和请求传给mapper层,并把mapper的结果处理以后交给controller
controller:负责交互。接收请求并返回结果。
精髓:各司其职、单向依赖。有利于分层解耦,提高代码复用性,助于维护。
员工模块开发
该开发过程在资料对应ppt和视频中有讲解。这里只讲要点。
新增员工
需求:实现往数据库中插入员工信息,要求遵循约束:账号唯一,手机号和身份证合法,默认密码为123456
实现要点:
在执行sql语句时,如果发生冲突导致出现异常,比如员工的用户名重复了,违反唯一约束就会导致抛出异常。不做处理则在前端用户不知道发生了什么。我们要自定义错误处理(ExceptionHandler)捕获错误信息并响应给前端。
对应的dto中没有操作者的id。我们这里通过ThreadLocal获得操作者的id,传给封装新员工信息的对象。ThreadLocal是Java线程中的一种局部变量。ThreadLocal为每个线程提供一份单独的存储空间,具有线程隔离的效果,不同的线程之间不会相互干扰。通过它,我们可以从请求头中的jwt令牌获取当前操作者的id。
员工分页查询
需求:把员工按照一页十条数据展示在员工管理页面。分页时可以依据员工姓名查询。
实现要点:使用PageHelper插件,以及对应dto进行查询。注意结果的封装:
@Override
public PageResult page(EmployeePageQueryDTO employeePageQueryDTO) {
//调用PageHelper 开始分页
PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());
//执行查询
List<Employee> empList = employeeMapper.pageQuery(employeePageQueryDTO);
//解析和封装结果
Page<Employee> page = (Page<Employee>)empList;
return new PageResult(page.getTotal(), page.getResult());
}同时我们注意到,返回到前端日期的格式奇怪。这是因为我们没有配置好日期的返回格式。spring默认返回的是iso格式的日期,形如:2022-09-02T00:29:04 。但是,在接口测试中观察到,返回日期的格式为: [ 2026, 2, 15, 13, 56, 31 ] 。这是因为为了生成接口文档,配置类继承了WebMvcConfigurationSupport并实现注册自定义拦截器。使用了 extends WebMvcConfigurationSupport,Spring Boot 内部的条件注解 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 就会生效。结果就是:Spring 停止自动配置 JSON 转换器,改用定义的(或者空的)转换器。
所以我们需要在自定义的WebMvcConfiguration配置类中扩展spring MVC的消息转换器,统一日期的格式。
/**
* 扩展mvc框架的消息转换器
* @param converters
*/
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("开始扩展消息转换器...");
//创建一个消息转化器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//设置对象转换器,可以将Java对象转为json字符串
converter.setObjectMapper(new JacksonObjectMapper());
//将我们自己的转换器放入spring MVC框架的容器中
converters.add(0,converter);
}禁用/启用员工
需求:可以在员工管理界面禁止和启用员工,管理员工的登录权限。被禁止的员工无法登录。
实现要点:修改员工的status字段实现。这里我们可以在mapper层实现一个通用的更新员工字段的接口,拼接动态sql,从而减少开发的时间和维护成本。
<update id="update" parameterType="com.sky.entity.Employee">
update employee
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="name != null">
name = #{name},
</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="status != null">
status = #{status},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="updateUser != null">
update_user = #{updateUser}
</if>
</set>
where id = #{id}
</update>修改员工
需求:更新已有的员工信息。
实现要点:首先实现根据id查询回显员工的接口,然后实现修改员工的接口复用之前写好的动态sql即可。
导入分类管理模块
把官方资料中提供的文件复制到项目的对应目录即可。注意:最好根据mapper层->service层->controller层这一顺序导入。这样不会引起报错。