苍穹外卖02(新增员工,重复内容异常处理器,绑定当前用户ThreadLocal,日期格式问题,分页查询,启用禁用,编辑员工)

目录

一、员工管理-新增员工

1.需求分析和设计

2.代码开发

3 功能测试

接口文档测试

前后端联调测试

4 代码完善一:增加异常处理器

5 代码完善二:绑定当前用户名

(1) 准备ThreadLocal工具类

(2) 修改拦截器代码

(3) Service里获取当前用户

小结

二、员工管理-分页查询

1.需求分析和设计

2 代码开发

3 功能测试

 4.问题描述:操作时间字段显示有问题。

三、员工管理-启用禁用

1 需求分析与设计

2 代码开发

3 功能测试

四、员工管理-编辑员工

1 需求分析与设计

2 代码开发

3 功能测试


一、员工管理-新增员工

准备工作:

  1. 先把服务端启动:运行引导类

  2. 再把nginx启动:双击nginx.exe,去任务管理器里查看一下,如果有两个nginx进程就说明启动成功了

开发功能时的依赖:

  • 接口文档

1.需求分析和设计

产品原型

一般在做需求分析时,往往都是对照着产品原型进行分析,因为产品原型比较直观,便于我们理解业务。

后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。

新增员工原型:

根据接口文档写:

2.代码开发

//DTO类

package com.sky.dto;
import lombok.Data;
import java.io.Serializable;

@Data
public class EmployeeDTO implements Serializable {

    private Long id;

    private String username;

    private String name;

    private String phone;

    private String sex;

    private String idNumber;

}


--------------------
//EmployeeController中创建新增员工方法

@PostMapping
@ApiOperation("新增员工")
public Result addEmp(@RequestBody EmployeeDTO dto){
    log.info("新增员工:{}", dto);
    return employeeService.addEmployee(dto);
}


-------------------
//Result类定义了后端统一返回结果格式

package com.sky.result;
import lombok.Data;
import java.io.Serializable;

/**
 * 后端统一返回结果
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败
    private String msg; //错误信息
    private T data; //数据

    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }

    public static <T> Result<T> success(T object) {
        Result<T> result = new Result<T>();
        result.data = object;
        result.code = 1;
        return result;
    }

    public static <T> Result<T> error(String msg) {
        Result result = new Result();
        result.msg = msg;
        result.code = 0;
        return result;
    }

}


------------------
//在EmployeeService接口中声明新增员工方法

   /**
     * 新增员工
     * @param dto 员工信息
     * @return
     */
    Result addEmployee(EmployeeDTO dto);


--------------------
//在EmployeeServiceImpl中实现新增员工方法

@Override
public Result addEmployee(EmployeeDTO dto) {
    //封装实体类对象
    Employee employee = new Employee();
    //使用工具类BeanUtils把dto里的数据,拷贝到employee对象里
    BeanUtils.copyProperties(dto, employee);

    //补充数据
    //  默认密码
    employee.setPassword(DigestUtils.md5Hex(PasswordConstant.DEFAULT_PASSWORD));
    //  status状态:
    employee.setStatus(StatusConstant.ENABLE);
    //  createTime和updateTime
    LocalDateTime now = LocalDateTime.now();
    employee.setCreateTime(now);
    employee.setUpdateTime(now);
    //  createUser和updateUser:先写假数据
    employee.setCreateUser(10L);
    employee.setUpdateUser(10L);

    employeeMapper.insert(employee);

    return Result.success();
}


---------------------
//在sky-common模块com.sky.constants包下已定义StatusConstant.java

package com.sky.constant;

/**
 * 状态常量,启用或者禁用
 */
public class StatusConstant {

    //启用
    public static final Integer ENABLE = 1;

    //禁用
    public static final Integer DISABLE = 0;
}


---------------------
//在EmployeeMapper中声明insert方法

@Insert("INSERT INTO employee (name, username, password, phone, sex, id_number, status, create_time, update_time, create_user, update_user)" +
        "        VALUES (#{name}, #{username}, #{password}, #{phone}, #{sex}, #{idNumber}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
void insert(Employee employee);


--------------------
//在application.yml中已开启驼峰命名,故id_number和idNumber可对应

mybatis:
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true

3 功能测试

接口文档测试

请求没有携带token测试报401

启动服务:访问http://localhost:8080/doc.html,进入新增员工接口

前后端联调测试

启动nginx,访问 http://localhost

登录-->员工管理-->添加员工

添加完成之后看数据库

4 代码完善一:增加异常处理器

问题说明

描述:录入的用户名已存,抛出的异常后没有处理

分析:

新增username=zhangsan的用户,若employee表中之前已存在,数据库有设置唯一unique。

后台报错信息:

增加异常处理器

通过全局异常处理器来处理。

进入到sky-server模块,com.sky.hander包下,GlobalExceptionHandler.java添加方法

/**
     * 处理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[] split = message.split(" ");
            String username = split[2];
            return Result.error(username + MessageConstant.ALREADY_EXISTS);
        }else{
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }

5 代码完善二:绑定当前用户名

问题说明

描述:新增员工时,创建人id和修改人id设置为固定值

通过某种方式动态获取当前登录员工的id

员工登录成功后会生成JWT令牌并响应给前端:

当前用户我们从jwt令牌中获取,可以直接一个传输,在你的类中直接创建,当然不是很方便,要每个类都传,这时候有个更好的办法放线程里

ThreadLocal介绍

源码:

多次访问我们的线程不会冲突,因为每次请求就会有一个新线程,线程里的一个map空间,以this当前的对象作为键key,以set设定的值作为value

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            map.set(this, value);
        } else {
            createMap(t, value);
        }
    }

介绍:

ThreadLocal 并不是一个Thread,而是Thread的局部变量。

每个线程都有单独一份存储空间,是一个HashMap,存取数据时以ThreadLocal对象为key,以存储的值为value

这个存储空间具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

常用方法:

  • public void set(T value) 设置当前线程的线程局部变量的值

  • public T get() 返回当前线程所对应的线程局部变量的值

  • public void remove() 移除当前线程的线程局部变量

对ThreadLocal有了一定认识后,接下来继续解决问题二

(1) 准备ThreadLocal工具类

初始工程中已经封装了 ThreadLocal 操作的工具类:

在sky-common模块

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();
    }

}
(2) 修改拦截器代码

在拦截器中解析出当前登录员工id,并放入线程局部变量中:

在sky-server模块中,拦截器:

package com.sky.interceptor;

/**
 * jwt令牌校验的拦截器
 */
@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 校验jwt
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
		//.............................
       
        //2、校验令牌
        try {
            //.................
            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);
            /将用户id存储到ThreadLocal
            BaseContext.setCurrentId(empId);
            
            //3、通过,放行
            return true;
        } catch (Exception ex) {
            //......................
        }
    }
}
(3) Service里获取当前用户

在Service中获取线程局部变量中的值:

小结

ThreadLocal的使用:
    作用:用于在同一线程内共享数据的
    用法:
        1. 创建ThreadLocal对象: ThreadLocal<管理的数据类型> tl = new ThreadLocal<>();
        2. 把数据绑定到当前线程上:tl.set(数据);
        3. 从当前线程上获取数据:  tl.get();
        4. 从当前线程上清理数据:  tl.remove();
    注意:
        一个ThreadLocal对象,只能管理一个数据。
            使用哪个ThreadLocal对象存储的数据,就必须用哪个ThreadLocal对象获取到这个数据
        当使用完成数据之后,一定要把数据从当前线程清理掉;否则可能会存在内存溢出的风险
    使用技巧:
        通常是创建一个类,类里提供静态的ThreadLocal对象,并提供存取数据的方法
            public class Xxxx{
                private static final ThreadLocal tl = new ThreadLocal();
                public static void setXxx(Xxx xxx){
                    tl.set(xxx);
                }
                public static Xxx getXxx(){
                    return tl.get();
                }
                public static void remove(){
                    tl.remove();
                }
            }
         如果需要绑定数据到当前线程:Xxxx.setXxx(值)
         如果需要从当前线程获取数据:Xxxx.getXxx()
         如果需要从当前线程清理数据:Xxxx.remote();

二、员工管理-分页查询

1.需求分析和设计

2 代码开发

//DTO类

package com.sky.dto;
import lombok.Data;
import java.io.Serializable;

@Data
public class EmployeePageQueryDTO implements Serializable {

    //员工姓名
    private String name;

    //页码
    private int page;

    //每页显示记录数
    private int pageSize;

}


-----------------
//后面所有的分页查询,统一都封装为PageResult对象。

package com.sky.result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * 封装分页查询结果
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {

    private long total; //总记录数

    private List records; //当前页数据集合

}


-----------------
//员工信息分页查询后端返回的对象类型为: Result<PageResult>

package com.sky.result;

import lombok.Data;

import java.io.Serializable;

/**
 * 后端统一返回结果
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败
    private String msg; //错误信息
    private T data; //数据

    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }

    public static <T> Result<T> success(T object) {
        Result<T> result = new Result<T>();
        result.data = object;
        result.code = 1;
        return result;
    }

    public static <T> Result<T> error(String msg) {
        Result result = new Result();
        result.msg = msg;
        result.code = 0;
        return result;
    }

}


------------------
//在sky-server模块中,com.sky.controller.admin.EmployeeController中添加分页查询方法。

/**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("员工分页查询")
    public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
        log.info("员工分页查询,参数为:{}", employeePageQueryDTO);
        PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);//后续定义
        return Result.success(pageResult);
    }


--------------------
//在EmployeeService接口中声明pageQuery方法

/**
     * 分页查询
     * @param employeePageQueryDTO
     * @return
     */
    PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);


--------------------
//在EmployeeServiceImpl中实现pageQuery方法:

/**
     * 分页查询
     *
     * @param employeePageQueryDTO
     * @return
     */
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        // select * from employee limit 0,10
        //开始分页查询
        PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());

        Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);//后续定义

        long total = page.getTotal();
        List<Employee> records = page.getResult();

        return new PageResult(total, records);
    }


------------------
**注意:**此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发。底层基于 mybatis 的拦截器实现。

故在pom.xml文中添加依赖(初始工程已添加)
<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper-spring-boot-starter</artifactId>
   <version>${pagehelper}</version>
</dependency>



-----------------
//在 EmployeeMapper 中声明 pageQuery 方法:


/**
     * 分页查询
     * @param employeePageQueryDTO
     * @return
     */
    Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);


------------------
//在 src/main/resources/mapper/EmployeeMapper.xml 中编写SQL:

<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>

3 功能测试

两种方式:

1.接口文档测试

请求没有携带token测试报401

启动服务:访问http://localhost:8080/doc.html,进入新增员工接口

2.前后端联调测试

启动nginx,访问 http://localhost

登录-->员工管理-->添加员工

 4.问题描述:操作时间字段显示有问题。

解决方式:

(1). 方式一

在属性上加上注解,对日期进行格式化

但这种方式,需要在每个时间属性上都要加上该注解,使用较麻烦,不能全局处理。

(2). 方式二(推荐 )

在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理

package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
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.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_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    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(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);
    }
}



-------------------------
//在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理

/**
     * 扩展Spring MVC框架的消息转化器
     * @param converters
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中
        converters.add(0,converter);
    }

三、员工管理-启用禁用

1 需求分析与设计

2 代码开发

//在sky-server模块中,根据接口设计中的请求参数形式对应的在 EmployeeController 中创建启用禁用员工账号的方法:

@PostMapping("/status/{status}")
@ApiOperation("启用/禁用员工帐号")
public Result updateStatus(@PathVariable("status") Integer status,
                           @RequestParam("id") Long empId){
    return employeeService.updateStatus(empId, status);
}


----------------
//在 EmployeeService 接口中声明启用禁用员工账号的业务方法:

 /**
     * 更新员工状态:启动/禁用
     * @param empId 员工id
     * @param status 状态
     * @return
     */
    Result updateStatus(Long empId, Integer status);


-------------------
//在 EmployeeServiceImpl 中实现启用禁用员工账号的业务方法:

@Override
public Result updateStatus(Long empId, Integer status) {
    //封装Employee对象
    Employee emp = Employee.builder().id(empId).status(status).build();
    //调用Mapper执行update语句
    employeeMapper.update(emp);
    
    return Result.success();
}


-----------------
//在 EmployeeMapper 接口中声明 update 方法:

/**
     * 根据主键动态修改属性
     * @param employee
     */
void update(Employee emp);


-------------------
//在 EmployeeMapper.xml 中编写SQL:

<update id="update">
    update employee
    <set>
        <if test="username!=null and username.length()>0">username=#{username},</if>
        <if test="name!=null and name.length()>0">name=#{name},</if>
        <if test="password!=null and password.length()>0">password=#{password},</if>
        <if test="phone!=null and phone.length()>0">phone=#{phone},</if>
        <if test="sex!=null and sex.length()>0">sex=#{sex},</if>
        <if test="status!=null">status=#{status},</if>
        <if test="updateTime!=null">update_time=#{updateTime},</if>
        <if test="createUser!=null">create_user=#{createUser},</if>
        <if test="updateUser!=null">update_user=#{updateUser},</if>
    </set>
    where id = #{id}
</update>

3 功能测试

1.接口文档测试

请求没有携带token测试报401

启动服务:访问http://localhost:8080/doc.html,进入新增员工接口

2.前后端联调测试

启动nginx,访问 http://localhost

package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
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.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_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    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(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);
    }
}



--------------------------
//在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理

/**
     * 扩展Spring MVC框架的消息转化器
     * @param converters
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中
        converters.add(0,converter);
    }

四、员工管理-编辑员工

1 需求分析与设计

2 代码开发

//在 EmployeeController 中创建 getById 方法

	/**
     * 根据id查询员工信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询员工信息")
    public Result<Employee> getById(@PathVariable Long id){
        Employee employee = employeeService.getById(id);
        return Result.success(employee);
    }


--------------
//在 EmployeeService 接口中声明 getById 方法:

 /**
     * 根据id查询员工
     * @param id
     * @return
     */
    Employee getById(Long id);


----------------
//在 EmployeeServiceImpl 中实现 getById 方法:

/**
     * 根据id查询员工
     *
     * @param id
     * @return
     */
    public Employee getById(Long id) {
        Employee employee = employeeMapper.getById(id);
        employee.setPassword("****");
        return employee;
    }


----------------
//在 EmployeeMapper 接口中声明 getById 方法:

/**
     * 根据id查询员工信息
     * @param id
     * @return
     */
    @Select("select * from employee where id = #{id}")
    Employee getById(Long id);


----------------
//在 EmployeeController 中创建 update 方法:

/**
     * 编辑员工信息
     * @param employeeDTO
     * @return
     */
    @PutMapping
    @ApiOperation("编辑员工信息")
    public Result update(@RequestBody EmployeeDTO employeeDTO){
        log.info("编辑员工信息:{}", employeeDTO);
        employeeService.update(employeeDTO);
        return Result.success();
    }


-----------------
//在 EmployeeService 接口中声明 update 方法:

/**
     * 编辑员工信息
     * @param employeeDTO
     */
    void update(EmployeeDTO employeeDTO);


-----------------
//在 EmployeeServiceImpl 中实现 update 方法:

/**
     * 编辑员工信息
     *
     * @param employeeDTO
     */
    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO, employee);

        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());

        employeeMapper.update(employee);
    }


3 功能测试

两种方式:

 1.接口文档测试

请求没有携带token测试报401

启动服务:访问http://localhost:8080/doc.html,进入新增员工接口

2.前后端联调测试

启动nginx,访问 http://localhost

  

最近更新

  1. TCP协议是安全的吗?

    2024-03-30 01:58:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-30 01:58:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-30 01:58:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-30 01:58:02       18 阅读

热门阅读

  1. 若干比赛题目以及补题复盘

    2024-03-30 01:58:02       18 阅读
  2. 十、Spring源码学习之onRefresh方法

    2024-03-30 01:58:02       17 阅读
  3. 学生管理系统——2

    2024-03-30 01:58:02       17 阅读
  4. 编程题 1

    2024-03-30 01:58:02       17 阅读
  5. AutoMQ 社区双周精选第九期((2024.03.11~2024.03.22)

    2024-03-30 01:58:02       21 阅读
  6. go的限流

    2024-03-30 01:58:02       16 阅读
  7. [Golang] RC4加解密

    2024-03-30 01:58:02       19 阅读
  8. 【更新中】Leetcode中遇到的最短路径算法

    2024-03-30 01:58:02       18 阅读
  9. python面试题(11~20)

    2024-03-30 01:58:02       21 阅读
  10. IT服务监督管理案例分析题

    2024-03-30 01:58:02       17 阅读