前言
该篇博客用于记录苍穹外卖第二天的学习——员工管理、分类管理接口开发,由于大多数知识与JavaWeb中的重复,这里只记录了那些新的知识以及我认为好的知识点。
新增员工接口
在这个接口有两个问题值得我们去完善1.录入重复的用户名,对异常进行处理。2.新增员工,创建人id和修改人id根据实际设置
问题1
当我们输入重复的用户名时,会报一个SQLIntegrityConstraintViolationException异常,这是因为在数据库中我们设置的用户名是unique,不允许重复,我们需要对这个异常进行处理。
处理方法为在handler包下的GlobalExceptionHandler里去定义一个处理该异常的方法。
//当我们定义重复用户名时会出现异常,在此我们来对改异常进行处理
@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){//定义对SQLIntegrityConstraintViolationException进行处理
//例如此时的异常信息为 Duplicate entry 'zhangsan' for key 'employee.idx_username
//获取异常信息
String message=ex.getMessage();
//如果包含异常信息
if(message.contains("Duplicate entry")){
//用空格将每个单词分开
String split[]=message.split(" ");
//获取用户名
String username=split[2];//zhangsan
//错误信息
String msg=username+ MessageConstant.ALREADY_EXITS;//用户名已存在
return Result.error(msg);
}else {
return Result.error(MessageConstant.UNKNOWN_ERROR);//位置错误
}
}
这样,以后在我们输入重复的用户名时,程序就不会停止,而是报出错误信息来提示我们了。
问题2
在之前新增员工时,我们是设置的固定值,而现在我们需要将创建人id和修改人id根据实际情况设置。
在解决此问题前,我想先介绍一个知识点ThreadLocal(提供线程局部变量)
ThreadLocal为每个线程单独提供一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外不能访问。也就是说,当你登录时,你就是一个单独的线程,你在ThreadLocal中存取数据对于其他线程来说是隔离的,只有你能访问当线程的数据。
- 用来存取数据 get()/set()
- 使用ThreadLocal存储的数据,线程安全
- 用完记得调用remove()方法释放,防止内存泄漏
ThreadLocal的上述方法在项目的sky-common中context包下的BaseContext类中已经提供好,想使用直接调用即可。
那么想要解决上述问题,我们只需将创建人id和修改人id通过set()方法先存到ThreadLocal中(),要使用的时候使用get()方法取出来即可。
很显然,在新增员工接口创建人id和修改人id就是登录者的id(empId),登录者的id我们在登录校验时校验令牌解析出来了,只需将该id存到ThreadLocal中即可
那么接下来我们只需将empId从ThreadLocal中取出来设置进去即可
employee.setCreateUser(BaseContext.getCurrentId());
employee.setUpdateUser(BaseContext.getCurrentId());
分页查询接口
分页查询接口的设计还挺有意思的,所以这里重点分析一下
分析接口文档可知这里的请求参数和返回参数,对应EmployeePageQueryDTO和PageResult,故controller层为
@GetMapping("/page")
@ApiOperation("员工分页查询")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
PageResult pageResult=employeeService.pageQuery(employeePageQueryDTO);
return Result.success(pageResult);
}
传统分页查询我们会写如以下SQL语句
select * from emp limit 0,10;
但在这我们使用一个mybatis提供给我们的插件PageHelper(记得引入依赖),它会做一个类似字符串拼接的操作,将limit 0,10拼接起来,其可以让我们简化分页代码的编写,使得我们的查询SQL语句只需如下
select * from emp;
在service层
//分页查询
@Override
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
//开始分页查询,传进页码和查询数量
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
//使用PageHelper,规定返回值必须为Page
Page<Employee> page=employeeMapper.pageQuery(employeePageQueryDTO);
//因为我们要返回的是一个PageResult,所以在这获取到总记录数和当前页面集合,构造出一个PageResult对象并返回
Long total=page.getTotal();
List<Employee> records=page.getResult();
return new PageResult(total,records);
}
在mapper层的XML映射文件中
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name!=null and name!=''">
-- 根据name查询
and name like concat ('%',#{name},'%')
</if>
</where>
order by create_time desc
</select>
另外:在PageHelper底层,其实也是用到了ThreadLocal,在service层它会将页码和每页记录数存进去,接着在分页查询之前再将页码和每页记录数取出来并加上limit关键字动态拼接到SQL语句中。
启用禁用员工
该接口没啥好说的,就略过了。
编辑员工信息
编辑员工功能,要求我们点击编辑之后,出现一个界面,展示员工原来的消息,然后可以修改员工的消息。该过程分为两步1.根据id查询到员工(@GetMapping)。2.查询到了后再编辑(@PutMapping)。故只需设计两个接口就可以完成此功能了。
分类管理接口与员工管理接口类似,可以自己实现一下。