苍穹外卖-第二天

该认真学习了,已经摆烂很久了

目录

完成任务(接口):

思路:

员工分页查询

启用禁用:

编辑员工:

公共字段自动填充

收获:

DTO和实体类

相关注解

逻辑外键

问题及解决:

启用禁用:


完成任务(接口):

  • 新增员工业务
  •  员工分页查询接口
  • 启用禁用员工账号
  • 编辑员工(通过id查询员工+编辑员工信息)
  • 导入分类管理功能模块
  • 公共字段自动填充

思路:

员工分页查询

本质仍然为employee单表的查询,每页展示10条数据,可以根据员工姓名查询

分析:GET请求

请求参数Query:需页码、每页记录数、员工姓名,

@Data
public class EmployeePageQueryDTO implements Serializable {

    //员工姓名
    private String name;

    //页码
    private int page;

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

}

后端响应:总记录数、每页的数据集合

public class PageResult implements Serializable {

    private long total; //总记录数

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

}

查询过程通过controller->service->mapper,在server中使用pagehelper来实现分页

    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        //select * from employee limit 1,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);
    }

在Mvc配置文件中增加自己的消息转换器,将日期格式转为"yyyy-MM-dd HH:mm"

protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器.....");
        //创建一个雄安锡转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为雄安锡转换器设置一个对象转换器,对象转换器可以将java对象序列转换为Jaso数据
        converter.setObjectMapper(new JacksonObjectMapper());
        
        //将自己的消息转换器加入容器中
        converters.add(0,converter);
    }
启用禁用:

相当与通过动态sql将获取的Id查询出来员工信息,然后将status的值改变

编辑员工:

接口:根据id查询员工(通过url参数)

           编辑员工                           

编辑员工可以使用update的sql

公共字段自动填充

由于在开发过程中,涉及到很多重复的代码,例如:插入、删除,在新增员工/编辑员工接口中都会用到,所以对其优化,使用APO切面,也就是将将这些方法通过自定义注解提前拦截,然后在通知中对其进行统一赋值

  • 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法(mapper中涉及insert、update的方法,通过AutoFill注解标识这些需要AOP的方法)
/**
 * 自定义注解,用于标识某个方法需要进行功能字段自动填充处理
 */
@Target(ElementType.METHOD)//指定这个注解只能加载到方法上 10个方法
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {

    //数据库操作类型,UPDATE,INSERT
    OperationType value();
}
  • 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值(定义切入点【拦截什么请求】和通知【对拦截的请求做什么额外的代码补充与增强】)
public class AutoFillAspect {

    /**
     * 切入点
     * 对哪些类的哪些方法进行拦截
     * 选择mapper包下带有AUtoFilL的注解
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}

    /**
     * 前置通知,在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始进行公共字段自动填充...");

        //获取当前被拦截的方法上的数据库操作类型
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();//方法签名对象
        AutoFill antoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType operationType = antoFill.value();//获得数据库操作类型

        //获取当前被拦截方法的参数--实体对象
        Object[] args = joinPoint.getArgs();//获得方法里的参数
        if (args==null || args.length==0)
            return;
        Object entity = args[0];//获得实体对象


        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //根据当前不同的操作类型,为对应的属性通过反射来赋值
        if (operationType==OperationType.INSERT){
            //为4个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setCreaterUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, long.class);

                //通过反射为对象属性赋值
                setCreateTime.invoke(entity,now);
                setCreaterUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);

            }catch (Exception e){
                e.printStackTrace();
            }

            
        }else if (operationType==OperationType.UPDATE){
            //为2个公共字段赋值
            try {
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

  • 在 Mapper 的方法上加入 AutoFill 注解
    @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})")
    @AutoFill(value = OperationType.INSERT)
    void insert(Employee employee);

收获:

DTO和实体类

entity:实体类,是用于说明某实体中所包含的所有属性,与数据库中的字段是保持一致的

DTO:数据传输对象,顾名思义,DTO是用于数据传输的,是根据实际的业务需求来决定这个对象具体包含哪些属性。是根据业务需要。里面包含了部分实体里面的属性用来完成业务,从而保证数据不暴露

在完成编辑员工接口时,在service实现类中,从控制层传入的时一个dto对象,这时可以通过BeanUtils.copyProperties来将dto的数据拷贝给实体对象,但里面需要修改的数据这时就要通过set来修改

public void update(EmployeeDTO employeeDTO) {
        Employee employee=new Employee();
        BeanUtils.copyProperties(employeeDTO,employee);

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

        employeeMapper.update(employee);

    }
相关注解

getDeclaredMethod() 获取的是类自身声明的所有方法,包含public、protected和private方法。

getMethod () 获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法

逻辑外键

逻辑外键是在关系数据库中的一个概念,它是通过程序或规则实现的关联关系,而不是通过数据库引擎的外键约束来实现的。

问题及解决:

启用禁用:

测试的时候一直有500的错误,传入的id是null,以为是sql语句有问题,改了好几遍,后来一行一行的debug,发现是在接口实现层中构建实体对象没有给他创建接受的employee,修改代码如下

public void startOrStop(Integer status, Long id) {
        //update employee set status=? where id=?

        //创建实体对象并设置值
        Employee employee=Employee.builder()
                .status(status)
                .id(id)
                .build();

        employeeMapper.update(employee);

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值