功能开发-员工信息维护
一、新增员工功能
1.1、需求分析
1.2、程序执行流程
1.3、代码开发
EmployeeContrroller
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
/**
* 员工注销
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
HttpSession session = request.getSession();
session.removeAttribute("employee");
return R.success("退出成功");
}
/**
* 新增员工
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> addEmployee(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工:{}",employee.toString());
// 1.编写新员工信息
// 设置初始密码123456,用MD5加密
String pwd = DigestUtils.md5DigestAsHex("123456".getBytes());
employee.setPassword(pwd);
// 账号更新时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 账号更新人
employee.setCreateUser((Long) request.getSession().getAttribute("employee"));
employee.setUpdateUser((Long) request.getSession().getAttribute("employee"));
// 2.通过业务层保存
employeeService.save(employee);
return R.success("新增员工成功");
}
}
1.4、测试
二、全局异常处理
我们在新增员工测试中发现当添加员工添加相同username程序会报错,因为我们设数据库中的employee表的username字段为唯一索引,因为我们还有n多个这样的表,我们选择全局异常处理,而不是单独的try/catch
2.1、需求分析
2.2、代码开发
package com.xxxit.reggie.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLIntegrityConstraintViolationException;
@Slf4j
@ControllerAdvice(annotations = {Controller.class, RestController.class})
@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
// 输出异常信息
log.info(ex.getMessage());
// 查看是否Duplicate entry,切分语句Duplicate entry 'zhangsan' for key 'employee.idx_username'
// 返回{username}已存在
if (ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2]+"已存在";
return R.error(msg);
}
return R.error("未知错误");
}
}
三、员工信息分页查询
3.1、需求分析
3.2、程序执行流程
前端把post参数用js变成路径参数
3.3、代码开发
3.3.1、新增分页拦截器
package com.xxxit.reggie.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 配置MP分页插件
*/
@Configuration
public class MyBatisPlusConfig {
@Bean //第三方对象创建为bean管理
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
3.3.2、编写Controller
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
/**
* 员工注销
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
HttpSession session = request.getSession();
session.removeAttribute("employee");
return R.success("退出成功");
}
/**
* 新增员工
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> addEmployee(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工:{}",employee.toString());
// 1.编写新员工信息
// 设置初始密码123456,用MD5加密
String pwd = DigestUtils.md5DigestAsHex("123456".getBytes());
employee.setPassword(pwd);
// 账号更新时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 账号更新人
employee.setCreateUser((Long) request.getSession().getAttribute("employee"));
employee.setUpdateUser((Long) request.getSession().getAttribute("employee"));
// 2.通过业务层保存
employeeService.save(employee);
return R.success("新增员工成功");
}
/**
* 查询员工分页功能
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
log.info("page = {},pageSize = {},name = {}",page,pageSize,name);
// 构造分页构造器
Page pageInfo = new Page(page, pageSize);
LambdaQueryWrapper<Employee> lqs = new LambdaQueryWrapper<>();
// 添加过滤条件
lqs.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 添加排序条件
lqs.orderByDesc(Employee::getUpdateTime);
// 通过service业务层执行,自动存到pageInfo
employeeService.page(pageInfo,lqs);
// 返回结果集
log.info(String.valueOf(pageInfo));
return R.success(pageInfo);
}
}
四、启用/禁用员工账号
4.1、需求分析
4.2、程序执行流程
4.3、代码开发
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
/**
* 员工注销
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
HttpSession session = request.getSession();
session.removeAttribute("employee");
return R.success("退出成功");
}
/**
* 新增员工
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> addEmployee(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工:{}",employee.toString());
// 1.编写新员工信息
// 设置初始密码123456,用MD5加密
String pwd = DigestUtils.md5DigestAsHex("123456".getBytes());
employee.setPassword(pwd);
// 账号更新时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 账号更新人
employee.setCreateUser((Long) request.getSession().getAttribute("employee"));
employee.setUpdateUser((Long) request.getSession().getAttribute("employee"));
// 2.通过业务层保存
employeeService.save(employee);
return R.success("新增员工成功");
}
/**
* 查询员工分页功能
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
log.info("page = {},pageSize = {},name = {}",page,pageSize,name);
// 构造分页构造器
Page pageInfo = new Page(page, pageSize);
LambdaQueryWrapper<Employee> lqs = new LambdaQueryWrapper<>();
// 添加过滤条件
lqs.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 添加排序条件
lqs.orderByDesc(Employee::getUpdateTime);
// 通过service业务层执行,自动存到pageInfo
employeeService.page(pageInfo,lqs);
// 返回结果集
log.info(String.valueOf(pageInfo));
return R.success(pageInfo);
}
@PutMapping
public R<String> EmployeeUpdate(HttpServletRequest request,@RequestBody Employee employee){
log.info(employee.toString());
// 1.通过业务层service,让service再通过mapper层去修改数据
// 获取修改人
Long empId = (Long) request.getSession().getAttribute("employee");
// 更改账号更新时间
employee.setUpdateTime(LocalDateTime.now());
employeeService.updateById(employee);
// 2.返回修改成功
return R.success("员工信息修改成功");
}
}
4.4、测试
程序没有报错,没有更改成功
4,5、代码修复
我们现在使用的是SpringMVC的默认消息转换器,我们需要再创建一个消息转换器,并让其优先级最高
JacksonObjectMapper
package com.xxxit.reggie.common;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
WebMvcConfig
package com.xxxit.reggie.config;
import com.xxxit.reggie.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Configuration
@Slf4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 静态资源映射
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始进行静态资源映射...");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
/**
* 扩展消息转换器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展消息转换器");
// 创建消息转换器
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
// 设置具体对象映射器
messageConverter.setObjectMapper(new JacksonObjectMapper());
super.extendMessageConverters(converters);
// 把我们的消息转换器优先级放到最高
converters.add(0,messageConverter);
}
}
五、编制员工信息
5.1、需求分析
5.2、程序执行流程
5.3、代码开发
package com.xxxit.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxit.reggie.common.R;
import com.xxxit.reggie.entity.Employee;
import com.xxxit.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired //自动装载
private EmployeeService employeeService;
/**
* 员工登录
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){
// 1.将页面提供password使用md5加密
String pwd = employee.getPassword();
pwd = DigestUtils.md5DigestAsHex(pwd.getBytes());
// 2.查询用户名是否存在数据库
// 相当于写了一个sql语句
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
//查询
Employee e = employeeService.getOne(queryWrapper);
// 3.没有查询到,返回登录失败
if (e == null) {
return R.error("用户名不存在或密码错误,登录失败~");
}
// 4.密码错误,返回登录失败
if (!e.getPassword().equals(pwd)){
return R.error("用户名不存在或密码错误,登录失败~");
}
// 5.账号被停用
if (e.getStatus() != 1){
return R.error("账号已被停止使用");
}
// 6.登录成功,先存到Session
HttpSession session = request.getSession();
session.setAttribute("employee",e.getId());
return R.success(e);
}
/**
* 员工注销
* @param request
* @return
*/
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request){
//清理Session中保存的当前登录员工的id
HttpSession session = request.getSession();
session.removeAttribute("employee");
return R.success("退出成功");
}
/**
* 新增员工
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> addEmployee(HttpServletRequest request,@RequestBody Employee employee){
log.info("新增员工:{}",employee.toString());
// 1.编写新员工信息
// 设置初始密码123456,用MD5加密
String pwd = DigestUtils.md5DigestAsHex("123456".getBytes());
employee.setPassword(pwd);
// 账号更新时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 账号更新人
employee.setCreateUser((Long) request.getSession().getAttribute("employee"));
employee.setUpdateUser((Long) request.getSession().getAttribute("employee"));
// 2.通过业务层保存
employeeService.save(employee);
return R.success("新增员工成功");
}
/**
* 查询员工分页功能
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
log.info("page = {},pageSize = {},name = {}",page,pageSize,name);
// 构造分页构造器
Page pageInfo = new Page(page, pageSize);
LambdaQueryWrapper<Employee> lqs = new LambdaQueryWrapper<>();
// 添加过滤条件
lqs.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 添加排序条件
lqs.orderByDesc(Employee::getUpdateTime);
// 通过service业务层执行,自动存到pageInfo
employeeService.page(pageInfo,lqs);
// 返回结果集
log.info(String.valueOf(pageInfo));
return R.success(pageInfo);
}
@PutMapping
public R<String> EmployeeUpdate(HttpServletRequest request,@RequestBody Employee employee){
log.info(employee.toString());
// 1.通过业务层service,让service再通过mapper层去修改数据
// 获取修改人
Long empId = (Long) request.getSession().getAttribute("employee");
// 更改账号更新时间
employee.setUpdateUser(empId);
employee.setUpdateTime(LocalDateTime.now());
employeeService.updateById(employee);
// 2.返回修改成功
return R.success("员工信息修改成功");
}
/**
* 根据id查询员工信息
* @param id
* @return
*/
@GetMapping("/{id}")
public R<Employee> getById(@PathVariable Long id){
log.info("根据id查询员工信息");
// 1.查询
Employee employee = employeeService.getById(id);
// 2.返回结果
return R.success(employee);
}
}