在EmployeeMapper.java中插入数据:一、新增员工
1.产品原型
2.接口设计
由于需要提交员工信息,用post请求方式,可以携带json数据
3.设计数据库的employee表
4.设计DTO
数据传输对象(DTO):封装前端提交过来的数据
实体类如下:包含更多属性
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String name;
private String password;
private String phone;
private String sex;
private String idNumber;
private Integer status;
//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
private Long createUser;
private Long updateUser;
}
5.开发
在EmployeeController.java中创建新增员工的方法:
说明:接收前端的HTTP POST请求,将请求体中的JSON数据转换为
EmployeeDTO
对象,记录日志,调用业务逻辑层的save方法来保存员工数据,并返回一个成功的响应
/**
* 新增员工
* @param employeeDTO
* @return
*/
@PostMapping //表明此方法用来处理客户端发送的POST请求
@ApiOperation("新增员工") //为API提供文档说明
//@RequestBody主要用来接收前端传递给后端的json对象,并将该对象自动转换为EmployeeDTO类型的实例
public Result save(@RequestBody EmployeeDTO employeeDTO){
log.info("新增员工:{}",employeeDTO); //日志记录,{}是占位符,用于插入变量的值
employeeService.save(employeeDTO); //该方法后续步骤会定义,用于处理保存的逻辑
return Result.success(); //Result是自定义的类,用于封装API方法的响应数据
}
在EmployeeService.java中声明新增员工方法:
/**
* 新增员工
* @param employeeDTO
*/
void save(EmployeeDTO employeeDTO);
在实现类EmployeeServicelmpl.java中实现新增员工方法:
说明:将
EmployeeDTO
对象转换为Employee
对象并保存到数据库中
/**
* 新增员工
*
* @param employeeDTO
*/
public void save(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
//将EmployeeDTO对象的属性复制到Employee对象中
BeanUtils.copyProperties(employeeDTO, employee);
//设置账号的状态,默认正常状态 1表示正常 0表示锁定
employee.setStatus(StatusConstant.ENABLE);
//设置密码,默认密码123456
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
//设置当前记录的创建时间和修改时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
//设置当前记录创建人id和修改人id
employee.setCreateUser(10L);//目前写个假数据,后期修改
employee.setUpdateUser(10L);
employeeMapper.insert(employee);//后续步骤定义,将Employee对象保存到数据库中
}
在EmployeeMapper.java中插入员工数据:
说明:使用MyBatis框架的Java接口方法,定义了插入员工数据到数据库的操作
/**
* 插入员工数据
* @param employee
*/
//@Insert是一个MyBatis框架的注解,用来指定SQL插入语句
//#{name}、#{username}等是MyBatis的参数占位符,它们将被实际的员工对象属性值所替换
@Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +
"values " +
"(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")
void insert(Employee employee);
6.功能测试
(1)通过前后端联调测试
由于前后端并行开发,后端开发完之后,前端可能没有开发完成,因此此方法局限性大,不常用
添加成功
(2)通过接口文档测试
在接口文档中的员工登录中生成一个jwt令牌,复制到全局参数设置中,刷新页面(令牌会2小时后失效,若报错401的话需要重新生成令牌)
在新增员工中自动添加了请求头部,此时发送请求就可以返回响应,数据库中成功添加了数据
7.代码完善
(1)录入的用户名已存在,抛出异常后没有处理
当重新提交zhangsan的数据时,因数据重复会抛出异常,需要重写异常
说明:异常处理方法,它使用了Spring框架的
@ExceptionHandler
注解来捕获并处理特定的异常类型:SQLIntegrityConstraintViolationException
/**
* 处理SQL异常
* @param ex
* @return
*/
@ExceptionHandler //捕获并处理特定的异常类型
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
//Duplicate entry 'zhangsan' for key 'employee.idx_username'
String message = ex.getMessage(); //获取异常的详细信息
if(message.contains("Duplicate entry")){
String[] sp = message.split(" "); //通过空格分割异常消息,然后提取用户名
String username = sp[2];
String msg = username + MessageConstant.ALREADY_EXISTS; //自定义的错误消息:用户已存在
return Result.error(msg);
}else {
return Result.error(MessageConstant.UNKNOWN_ERROR);//自定义的错误消息:未知错误
}
}
(2)新增员工时,创建人id和修改人id设置为了固定值
需要通过某种方式动态获取当前登录员工的id
客户端发送的每一个请求对应一个线程,因此可以把id存入ThreadLocal,再在server里取出来
在使用ThreadLocal时往往会进行一个简单的封装,包装成一个工具类common-context-BaseContext
package com.sky.context;
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}
需要在JwtTokenAdminlnterceptor.java拦截器取出ID:
BaseContext.setCurrentId(empId);
需要在EmployeeServicelmpl.java实现类获得ID:
//设置当前记录创建人id和修改人id
employee.setCreateUser(BaseContext.getCurrentId());
employee.setUpdateUser(BaseContext.getCurrentId());
二、员工分页查询
1.产品原型
2.接口设计
3.设计DTO
4.开发
在EmployeeController.java中创建员工分页查询的方法:
/**
* 员工分页查询
* @param employeePageQueryDTO
* @return
*/
@GetMapping("/page")
@ApiOperation("员工分页查询")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
log.info("员工分页查询,参数为:{}", employeePageQueryDTO);
PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO); //service存储分页查询的方法
return Result.success(pageResult);
}
在EmployeeService.java中声明员工分页查询方法:
/**
* 分页查询方法
* @param employeePageQueryDTO
* @return
*/
PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
在实现类EmployeeServicelmpl.java中实现员工分页查询方法:
说明:使用mybatis中的pagehelper插件,已经在初始代码pom.xml中引入,可以简化分页操作,
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
/**
* 分页查询
* @param employeePageQueryDTO
* @return
*/
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
//select * from employee limit 0,10(limit关键字查询第0-10条)
//实现原理:将page封装后存入threadlocal,在分页查询前取出来,动态拼接实现SQL
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO); //返回pagehelper格式的对象
long total = page.getTotal();
List<Employee> records = page.getResult();
return new PageResult(total, records);
}
在EmployeeMapper.java中插入数据:
/**
* 员工分页查询
* @param employeePageQueryDTO
* @return
*/
Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);
说明:使用动态SQL,不再使用注解的方式,需要写到映射文件server-resources-mapper-EmployeeMapper.xml中
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.EmployeeMapper">
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name != null and name != ''">
and name like concat('%',#{name},'%')
</if>
</where>
order by create_time desc
</select>
</mapper>