三层架构
Controller 类前使用 @RestController,
@Api(使接口文档更清晰明了),
@RequestMapping(当前类下所有方法的公共url前缀),
@Slf4j(在后端控制台输出日志 log.info(“…”))。
类中使用 @Autowired 注入 Service 接口依赖。
新增使用 post 请求,对应 @PostMapping 注解,insert语句。
删除使用 delete 请求,对应 @DeleteMapping 注解,delete语句。
修改使用 put 请求,对应 @PutMapping 注解,update语句。
查询使用 get 请求,对应 @GetMapping 注解,select语句。
ServiceImpl 类前使用 @Servicr。实现 Service 接口,要使用 implements 关键字。
类中使用 @Autowired 注入 Mapper 接口依赖。
Mapper 接口前使用 @Mapper
employee表结构
| 字段名 | 数据类型 | 说明 | 备注 |
|---|---|---|---|
| id | bigint | 主键 | 自增 |
| name | varchar(32) | 姓名 | |
| username | varchar(32) | 用户名 | 唯一 |
| password | varchar(64) | 密码 | |
| phone | varchar(11) | 手机号 | |
| sex | varchar(2) | 性别 | |
| id_number | varchar(18) | 身份证号 | |
| status | Int | 账号状态 | 1正常 0锁定 |
| create_time | Datetime | 创建时间 | |
| update_time | datetime | 最后修改时间 | |
| create_user | bigint | 创建人id | |
| update_user | bigint | 最后修改人id |
其中,employee表中的status字段已经设置了默认值1,表示状态正常。
1. 新增员工
注意:当前端提交的数据和实体类中对应的属性差别比较大时,建议使用DTO来封装数据。
xxxServiceImpl 类实现 xxxService 接口的方法可用 ctrl + i 自动生成。
1.1 代码实现逻辑
Impl:
new一个对象,用 BeanUtils.copyProperties(xxxDTO, xxx); 将DTO拷贝过来,补齐DTO中缺少的属性
Mapper:
SQL语句写在 @Insert 注解中 “insert into 表名 属性列表 values 参数列表”,在application.yml中已开启驼峰命名,故id_number和idNumber可对应。
1.2 接口文档中添加令牌(防止JWT校验失败而无法正常测试)
使用admin用户登录获取令牌
将合法的JWT令牌添加到全局参数中:
文档管理–>全局参数设置–>添加参数
1.3 动态获取当前登录员工的id
员工登录成功后会生成JWT令牌并响应给前端,后续请求中,前端会携带JWT令牌,通过JWT令牌可以解析出当前登录员工id:JwtTokenAdminInterceptor.java
1 | package com.sky.interceptor; |
思考:解析出登录员工id后,如何传递给Service的save方法?
通过ThreadLocal进行传递。
1.3.1 ThreadLocal
介绍:
ThreadLocal 并不是一个Thread,而是Thread的局部变量。 ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
常用方法:
- public void set(T value) 设置当前线程的线程局部变量的值
- public T get() 返回当前线程所对应的线程局部变量的值
- public void remove() 移除当前线程的线程局部变量
初始工程中已经封装了 ThreadLocal 操作的工具类 BaseContext。
在拦截器中解析出当前登录员工id,并放入线程局部变量中:JwtTokenAdminInterceptor.java
1 | //2、校验令牌 |
在ServiceImpl中获取线程局部变量中的值:
1 | /** |
2. 员工分页查询
注意事项:请求参数类型为Query,不是json格式提交,在路径后直接拼接。/admin/employee/page?name=zhangsan,返回数据中records数组中使用Employee实体类对属性进行封装。后面所有的分页查询,统一都封装为PageResult对象。
2.1 代码实现逻辑
在 xxxImpl 中实现 pageQuery 方法。
1 | /** |
注意:此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发。底层基于 mybatis 的拦截器实现。
在 src/main/resources/mapper/EmployeeMapper.xml 中编写SQL:
1 | <select id="pageQuery" resultType="com.sky.entity.Employee"> |
2.2 日期时间格式化
在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理
1 | /** |
时间格式定义,sky-common模块中
1 | package com.sky.json; |
3. 启用禁用员工账号
业务规则:
- 可以对状态为“启用” 的员工账号进行“禁用”操作
- 可以对状态为“禁用” 的员工账号进行“启用”操作
- 状态为“禁用”的员工账号不能登录系统
3.1 代码实现逻辑
xxx.buidler().build()中间加入关键属性设置。
在 EmployeeServiceImpl 中实现启用禁用员工账号的业务方法:
1 | /** |
在 EmployeeMapper.xml 中编写SQL:
1 | <update id="update" parameterType="Employee"> |
4. 编辑员工
注:点击修改时,数据应该正常回显到修改页面。
根据上述分析,编辑员工功能涉及到两个接口:
- 根据id查询员工信息
- 编辑员工信息
4.1代码实现逻辑
根据id查询员工信息(getById)
密码不回显,故在 Impl 的方法中要有employee.setPassword(“****”);
编辑员工信息
Impl:
new一个对象,用 BeanUtils.copyProperties(xxxDTO, xxx); 将DTO拷贝过来,补齐DTO中缺少的属性(更新时间、更新人),update已在启用禁用员工时写好。
category表结构:
| 字段名 | 数据类型 | 说明 | 备注 |
|---|---|---|---|
| id | bigint | 主键 | 自增 |
| name | varchar(32) | 分类名称 | 唯一 |
| type | int | 分类类型 | 1菜品分类 2套餐分类 |
| sort | int | 排序字段 | 用于分类数据的排序 |
| status | int | 状态 | 1启用 0禁用 |
| create_time | datetime | 创建时间 | |
| update_time | datetime | 最后修改时间 | |
| create_user | bigint | 创建人id | |
| update_user | bigint | 最后修改人id |
5.分类管理
根据原型分析,菜品分类模块共涉及6个接口。
- 新增分类
- 分类分页查询
- 根据id删除分类
- 修改分类
- 启用禁用分类
- 根据类型查询分类
原理与员工管理一样,略。