猿创征文|瑞吉外卖——管理端_员工管理

个人名片:

博主酒徒ᝰ.
专栏瑞吉外卖
个人简介沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志一本好书,就像高级武功秘籍一样,哪怕只是从里面领悟到个一招半势,功力提升起来都是惊人的。

本项目基于B站黑马程序员Java项目实战《瑞吉外卖》,轻松掌握springboot + mybatis plus开发核心技术的真java实战项目。

视频链接【黑马程序员Java项目实战《瑞吉外卖》,轻松掌握springboot + mybatis
plus开发核心技术的真java实战项目】 https://www.bilibili.com/video/BV13a411q753?
点击观看

一、页面呈现

在这里插入图片描述

分析:employee地址,GET方式,page地址。在?后面有page和pageSize
数据库中:name为非空,所以此处直接查询数据库中Employee表的所以内容。

/**
* 页面呈现——分页查询
* @param page
* @param pageSize
* @return
*/
@GetMapping("/page")
public R<Page> page(int page, int pageSize){
    //测试是否可以接收到信息
    //        log.info("page:{},pageSize:{}",page, pageSize);

    //分页构造器
    Page<Employee> pageInfo = new Page<>(page, pageSize);

    //查询Employee表中全部信息
    LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.orderByDesc(Employee::getUpdateTime);
    employeeService.page(pageInfo, queryWrapper);

    return R.success(pageInfo);
}

二、添加员工

1. 原始操作

在这里插入图片描述

分析:Post方式,employee地址
在这里插入图片描述

此表格与数据库员工表存在查询,内容不够,缺少的部分如果是非空(都是非空)就需要补全。
状态码(status)默认为1,无需补。

/**
* 添加员工信息
* @param request
* @param employee
* @return
*/
@PostMapping
public R<String> employee(HttpServletRequest request, @RequestBody Employee employee){
    //测试信息,对照数据库,查看需要补充哪些信息。
    //log.info("employee:{}",employee);//employee:Employee(id=null, name=88, username=888, password=null, phone=13452525252, sex=1, idNumber=111111111111111111, status=null, createTime=null, updateTime=null, createUser=null, updateUser=null)
    //需要补充password=null, status=null, createTime=null, updateTime=null, createUser=null, updateUser=null
    //设置初始密码 123456
    employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
    //设置其它 时间类 当前时间
    employee.setCreateTime(LocalDateTime.now());
    employee.setUpdateTime(LocalDateTime.now());
    //设置其它 名字 用户名(返回之前在登录时保存) 用户名id为Long形式
    Long empId = (Long)request.getSession().getAttribute("employee");
    employee.setCreateUser(empId);
    employee.setUpdateUser(empId);

    employeeService.save(employee);
    return R.success("添加员工成功");
}

2. 优化操作

在上述的代码操作下,每一次的添加与修改操作时,我们都需要执行以下代码。

//设置其它 时间类 当前时间
    employee.setCreateTime(LocalDateTime.now());
    employee.setUpdateTime(LocalDateTime.now());
    //设置其它 名字 用户名(返回之前在登录时保存) 用户名id为Long形式
    Long empId = (Long)request.getSession().getAttribute("employee");
    employee.setCreateUser(empId);
    employee.setUpdateUser(empId);

这是比较繁琐的,因此,需要进行一些操作来简化开发。 我们需要一个操作,在每一次的添加与修改时,都会自动进行这些操作

代码示例:

package com.itheima.reggie.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Component
public class MyMetaObjecthandler implements MetaObjectHandler {

    /**
     * 插入操作时自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        Long empId = (Long)request.getSession().getAttribute("employee");
        metaObject.setValue("createUser", emp);
        metaObject.setValue("updateUser", emp);
    }

    /**
     * 更新操作时自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        metaObject.setValue("updateTime", LocalDateTime.now());
        Long empId = (Long)request.getSession().getAttribute("employee");
        metaObject.setValue("updateUser", emp);
    }
}

进一步简化:

这里的设置与获取ID值,必须保证在登录后一定已经设置。我的操作时在之后的登陆过滤器中设置ID。

package com.itheima.reggie.common;

/**
 * 用户保存和获取当前登录的用户ID,便于在添加与修改人是可以快速获取。
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    /**
     * 设置id值
     * @param id
     */
    public static void setCurrentId(Long id) {
        threadLocal.set(id);
    }

    /**
     * 获取id值
     * @return
     */
    public static Long getCurrentId() {
        return threadLocal.get();
    }

}

package com.itheima.reggie.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Component
public class MyMetaObjecthandler implements MetaObjectHandler {

    /**
     * 插入操作时自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }

    /**
     * 更新操作时自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateCreate", BaseContext.getCurrentId());
    }
}

三、编辑(修改员工)

1.回显数据

在这里插入图片描述

地址对照数据库可以发现是对照员工表中的id来进行修改的。

/**
* 数据回显
* @param id
* @return
*/
@GetMapping("/{id}")
public R<Employee> huixian(@PathVariable Long id){
    //根据前端传过来的id进行查询信息
    LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Employee::getId, id);
    Employee employee = employeeService.getOne(queryWrapper);
    return R.success(employee);
}

功能测试:发现测试出问题了,并没有回显数据。查看日志发现,浏览器的id与数据库中的ID不一样。这是因为数据精度丢失。

解决办法

修改id将其变为字符串形式。
这里用到了之前加入的对象映射器。
在使用消息转换器将Long类型数据转换为String类型

/**
 * 消息转换器
 * @param converters the list of configured converters to extend
 */
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    //创建消息转化器对象
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    //将java对象转为json对象
    messageConverter.setObjectMapper(new JacksonObjectMapper());
    converters.add(0,messageConverter);
}

2.修改数据

在这里插入图片描述

分析:PUT方法

/**
 * 修改数据
 * @param employee
 * @return
 */
@PutMapping
public R<String> employee(@RequestBody Employee employee){
    employeeService.updateById(employee);
    return R.success("修改成功");
}

四、输入框查找

在这里插入图片描述

分析:GET方式,相对于页面呈现来说,添加了一个name属性。
发现与页面呈现使用的都是@GetMapper(“/page”),所以需要在页面呈现中进行修改。
修改后为:(仅仅添加判断name是否为空的判断)

/**
 * 页面呈现——分页查询
 * @param page
 * @param pageSize
 * @return
 */
@GetMapping("/page")
public R<Page> page(int page, int pageSize, String name){
    //测试是否可以接收到信息
//    log.info("page:{},pageSize:{},name:{}",page, pageSize, name);

    //分页构造器
    Page<Employee> pageInfo = new Page<>(page, pageSize);

    //查询Employee表中全部信息
    LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.orderByDesc(Employee::getUpdateTime);

    //输入框查找添加
    if (name != null){
        queryWrapper.like(Employee::getName,name);
    }

    employeeService.page(pageInfo, queryWrapper);

    return R.success(pageInfo);
}

五、知识点

1. 消息转换器

json数据中int转string:这个可以使用快捷键,会省略很多。

/**
 * 消息转换器
 * @param converters the list of configured converters to extend
 */
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    //创建消息转化器对象
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    //将java对象转为json对象
    messageConverter.setObjectMapper(new JacksonObjectMapper());
    converters.add(0,messageConverter);
}

对象映射器:这个在老师的资料里有,可以选择直接用。

package com.itheima.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);
    }
}

2. @pathVariable,@PathParam和RequestParam的区别:

  • @pathVariable:从路径中获取变量,也就是把路径当做变量,路径问号前面
    eg:http://localhost:8080/dish?ids=1413384757047271425中的dish
  • @PathParam从请求里面获取参数,从请求来看,路径问号后面eg:http://localhost:8080/dish?ids=1413384757047271425中的1413384757047271425
  • @RequestParam是从 request
    里面拿取值,是以键值对方式来获取参数值的。获取?后面相同一个属性的多个值。eg:http://localhost:8080/test?name=李四&name1=张三中的张三,李四。

3. ThreadLocal

这是一个本地线程,具有隔离性。在这里你需要确保每一个ID的唯一。
与Synchronized的区别是:
Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值