上一篇主要进行了员工信息的分页查询的功能完善,下面我们就可以实现一个员工的添加功能。
所以这里做的还是后台管理的功能。其实可以先看一个前端传过来的请求,先不用启动程序,直接打开页面先看一下。
当我们点击这个添加按钮的时候,我们可以捕捉到这些信息,图片的资源数据和一个html。
打开看一下。
那我们就到这个页面去看。这样我们可以很快找到这个页面、
打开的话其实是这样的一个表单
分析一个这个页面做了那些事情。首先调到这个页面肯定是是有一个表单的展示。像这样的部分都是一个展示框,要填写新增的信息的。然后呢!一定有一个保存的按钮,保存的按钮绑定到具体的方法,然后在这个方法里面我们就可以找到我们去具体处理数据的逻辑。
其实一定还会有一个取消的按钮,就是取消添加信息了,那么这个时候就会进行一个回退。我们去找找保存和回退的按钮。可以看到下面这里,其实还有一个保存和继续添加,很好理解
我们往下面看,下面会有具体的绑定的方法。这里是我们具体的保存的方法逻辑。这个方法还做了一些表单的验证。方法中嵌套着另一个方法,addEmployee。
我们点进去看这个链接。你看这里其实调到了一个js。在这里我们可以看到具体的提交路径,参数params是我们的提交的参数。这个参数是ruleForm。ruleForm是上方页面的数据绑定,里面就是我们员工的信息,这里的知识点就是vue的数据模型的双向绑定。我们在表单上进行的数据修改或者添加也会同步到我们的数据模型,所以我们实际上就是将自己填写的用户数据进行了一个分账类型的提交。没错,就是json类型的。
这里是回退,回退到我们原来的链接
所以在整个逻辑理清后,这里就是我们最终要取到的前端请求路径以及请求参数和提交方式。。
现在我们就可以写后端代码了。
其实还是在这个Controller类里面,这里的路径已经写上了一个employee
所以我们在这里写方法就行了。其他的类的准备我们在上一篇文章都已经准备好了.
那么现在我们开始写方法,方法的话真的很简单,只是需要注意一些细节,但是我认为这里面还是有我们去巩固学习的知识点。
来看,接收参数自然是没有问题的,我们用employee这个实体类去接收。
这个实体类有哪些字段呢?其实我们之前都看过,但是表单自然是不会去展示密码的,以及像修改时间,修改者这些等等,密码我们做成糊另外的处理,其他的其实属于我们上文提到的公共字段,所以我们让它自动填充了。
@PostMapping
public R_<String>save(HttpServletRequest request ,@RequestBody Employee employee)
{
log.info("新增员工,员工信息:{}",employee.toString());
// 设置初始密码123456,然后进行md5加密处理
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
// employee.setCreateTime(LocalDateTime.now());
// employee.setUpdateTime(LocalDateTime.now());
// 获得登录用户的id
// long empid = (long)request.getSession().getAttribute("employee");
// employee.setCreateUser(empid);
// employee.setUpdateUser(empid);
employService.save(employee);
return R_.success("新增员工成功");
}
这里我们对密码进行了一个md5加密,其实的话自己也可以去处理的,这里其实考虑到只要一个超级管理员吧,所以初始密码之后就进行md5加密了。
系统是把用户输入的密码计算成MD5值
//字符串密码md5加密
String md5Pass = DigestUtils.md5DigestAsHex(password.getBytes());
这个工具类依赖什么呢?就是这个依赖。依赖于这个依赖。
所以我们在使用工具和依赖的时候必须明白它到底是干嘛的。
最后调用了一个save方法,这个是mybatisplus的保存的一个方法。 如果进行insert操作的时候,不进行id的设置,也不传入id,这时它会给你自动添加一个id值,最奇怪的是这个id值默认好像是使用雪花算法生成的。其实我这里还在配置这里设置了主键的生成策略。雪花算法,
如果你想要主键比较整齐的话,可以采用自增策略。
我们最终的方法返回是R_类型,里面的泛型是String类型。
R_类的封装。
然后前端,所以我们后端返回什么样的数据一定程度上取决于前端的需求。
这样的分析基本就是一个闭环的分析,理清整个逻辑。
我们对于员工的账号给出了唯一的约束,我们可以去查看。id自然我们不会自己去手动添加的,但是username我们是需要手动添加的。
我们可以去看前端页面这里其实username对应的就是账号。
所以对于这个员工信息的添加啊,我们还需要注意一点就是如果我们的员工账号添加重复的话,我们数据库中指定它的账号是惟一的,如果重复插入的话,会报一个异常。这个异常是我们的数据库给出的。我们可以去处理捕获。现在我们去添加一个重复账号的信息。
数据库就会爆出下面的异常。因为usename是唯一约束,所以添加失败了。
因为我已经处理了,没处理的话,页面会给出500的异常码,然后控制台或者页面也应该给出下面这段话。
asaa添加重复,按照这个逻辑的话,我们就可以定义全局异常处理器,去截取具体的重复字段作为前端提示信息,这样我们就可以给出是哪个字段账号重复。
我们需要捕获这个sql异常 SQLIntegrityConstraintViolationException
其实就是违反了数据库的唯一约束条件!也就是插入数据时,具有唯一约束条件的列值重复了。
我们可以去做一个全局的异常处理器。
package com.jgdabc.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLIntegrityConstraintViolationException;
//全局异常处理器
//加注解指定拦截处理异常的Controller
@ResponseBody
@ControllerAdvice(annotations = {RestController.class,Controller.class})
@Slf4j
public class GlobalExceptionHander {
//进行异常处理
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public R_<String> exceptionHandeler(SQLIntegrityConstraintViolationException ex)
{
log.error(ex.getMessage());
if(ex.getMessage().contains("Duplicate entry")) {
String[] spl = ex.getMessage().split(" ");
String msg = spl[2]+ "已存在";
return R_.error(msg);
}
return R_.error("未知错误");
}
}
}
这里面设计几个人注解,下面引用再录自博客@ControllerAdvice
@ExceptionHandler(Exception.class)注解,表示当控制器抛出Exception异常时,将会委托该方法来处理。
@controllerAdvice最为实用的一个场景就是将所有@ExceptionHandler方法收集到一个类中,这样所有的异常都能在一个地方进行一致处理。
@ControllerAdvice是一个@Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
在Spring中, @ControllerAdvice通过annotations(), basePackageClasses(), basePackages() 方法定制用于选择控制器子集。
annotations:指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理。