projectruiji

导航

瑞吉外卖day3

分类管理

公共字段填充

问题分析

  代码实现

1.在实体类属性上加入@TableField注解,指定字段填充策略

 @TableField(fill = FieldFill.INSERT)//插入时填充字段
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新时填充字段
    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)//插入时填充字段
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新时填充字段

 

2.按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值。此类需要实现MetaObjectHandler接口  

@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入字段自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("插入字段自动填充");
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createTime",LocalDateTime.now());
        metaObject.setValue("createUser",new Long(1));
        metaObject.setValue("updateUser",new Long(1));

    }

    /**
     * 更新字段自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("更新字段自动填充");
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser",new Long(1));

    }
}

功能完善

此时在公共字段自动填充时,设置的updateUser和createUSer的值是固定的, 需要改进为动态获取updateUser和createUser的值

客户端每次发送http请求时,对应的服务端都会分配一个线程来处理,在处理过程中涉及到下面类中的方法都属于相同的一个线程:

1.LoginCheckFilter的doFilter方法

2.EmployeeController的update方法

3.MyMetaObjectHandler的updateFill方法

可以使用ThreadLocal来实现动态获取updateUser和createUser的值

ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
ThreadLocal常用方法:
. public void set(T value)设置当前线程的线程局部变量的值.

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

我们可以在LoginCheckFilter的doFilter方法中获取当前登录用户id,并调用ThreadLocal的set方法来设置当前线程的线程局部变量的值(用户id),然后在MyMetaObjectHandler的updateFill方法中调用ThreadLocal的get方法来获得当前线程所对应的线程局部变量的值(用户id)。
实现步骤

1.编写BaseContext工具类,基于ThreadLocal封装的工具类

**
 * 功能描述
 *  编写BaseContext工具类,基于ThreadLocal封装的工具类
 * @author 15599
 * @date 2023/05/09  8:40
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }
    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

 

2.在loginCheckFilter的doFilter方法中调用BaseContext来设置当前登录用户的id

3.在MyMetaObjectHandler的方法中调用BaseContext来获取登录用户的id

 

新增分类

需求分析

后台系统中可以管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。当我们在后台系统中添加菜品时需要选择一个菜品分类,当我们在后台系统中添加一个套餐时需要选择一个套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐。

 代码开发

类和基本结构

  • 实体类Category
  • Mapper接口CateGoryMApper
  • 业务层接口CategoryService
  • 业务层接口实现类CategoryServiceImpl
  • 控制层CategoryController

 代码开发

@PostMapping
    public R<String> save(@RequestBody  Category category){
        log.info("category={}",category);
        categoryService.save(category);
        return R.success("新增分类成功");
    }

 分类信息分页查询

 @GetMapping("/page")
    public R<Page> page(int page,int pageSize){
        Page<Category> pageInfo = new Page<>(page,pageSize);
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.orderByAsc(Category::getSort);
        categoryService.page(pageInfo,queryWrapper);
        return R.success(pageInfo);
    }

删除分类

需求分析

在分类管理列表页面,可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除

代码实现

在CategoryService实现类中编写remove方法判断分类是否关联菜品或套餐

  @Override
    public void remove(Long id) {
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dish::getCategoryId,id);
        int count1 = dishService.count(queryWrapper);
        if (count1>0){
            //关联菜品。抛出异常
            throw  new CustomException("该菜品分类已经关联菜品,无法删除");
        }

        LambdaQueryWrapper<Setmeal> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Setmeal::getCategoryId,id);
        int count2 = setmealService.count(queryWrapper1);
        if (count2>0){
            //关联套餐  抛出异常
            throw  new CustomException("该菜品分类已经关联套餐,无法删除");

        }

        super.removeById(id);

    }

若关联菜品或套餐,则抛出自定义异常CustomException

public class CustomException extends RuntimeException{
    public CustomException(String message){
        super(message);

    }
}

在全局异常处理器中处理自定义异常

    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex){
        log.error(ex.getMessage());


        return R.error(ex.getMessage());
    }

修改分类

@PutMapping
    public R<String> update(@RequestBody Category category){
        log.info("修改分类信息{}",category);
        categoryService.updateById(category);
        return R.success("修改成功");

 

posted on 2023-05-09 18:54  十一H  阅读(28)  评论(0编辑  收藏  举报