天天看點

瑞吉外賣項目重點難點記錄一、公共字段的自動填充二、全局異常捕獲(重點)三、定義Result全局統一傳回結果類四、REST開發風格

一、公共字段的自動填充

在本項目中,大多數pojo中都有一些相同字段(createTime、updateTime、createUser、updateUser)等,為提高開發效率,可利用AOP切面技術來解決公共字段的指派問題。

在mybayis-plus中,提供了一個接口MetaObjectHandler,隻需要自定義一個類并實作它,在重寫insertFill和updateFill方法即可。

        insertFill方法在插入時可自動填充公共字段的屬性值

        updateFill方法在修改更新時可自動填充公共字段的屬性值

在metaObject.setValue("createTime", LocalDateTime.now())中,前一個屬性為要插入字段的屬性名,後面為需要賦予的值。

再在需要自動填充的字段寫上注解@TableField,後面括号為選擇在何時指派,FieldFill.INSERT為插入時指派,FieldFill.INSERT_UPDATE為插入和更新時指派,

@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)
    private Long updateUser;
           
@Component
public class MyMetaObjectionable implements MetaObjectHandler {
    @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());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}
           

二、全局異常捕獲(重點)

自定義一個異常捕獲類,加上@RestControllerAdvice,異常有使用者操作不規範異常,業務異常,和其他異常。在異常捕獲類中可自定義方法并用注解@ExceptionHandler,括号裡寫上要處理異常名.class即可捕獲到異常,在對異常進行處理即可。

@RestControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 賬号異常處理方法
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());
        if(ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
            String msg = split[2]+"已存在";
            return R.error(msg);
        }
        return R.error("未知錯誤");
    }

    /**
     * 删除時關聯了菜品或套餐異常
     * @param ex
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex){
        log.error(ex.getMessage());
        return R.error(ex.getMessage());
    }
}
           

三、定義Result全局統一傳回結果類

作用:可統一前後端資料互動的格式。

public class R<T> {

    private Integer code; //編碼:1成功,0和其它數字為失敗

    private String msg; //錯誤資訊

    private T data; //資料

    private Map map = new HashMap(); //動态資料

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

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

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}
           

四、REST開發風格

在Controller層中,類寫上注解@RestController,再在各個方法中寫上對應的注解即可,添加常用@PostMapping、更新修改常用@PutMapping、删除常用@DeleteMapping、查詢常用GetMapping

@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private CategoryService categoryService;
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
        Page<Dish> pageInfo=new Page<>(page,pageSize);
        Page<DishDto> dishDtoPage=new Page<>();

        LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotEmpty(name),Dish::getName,name);
        lqw.orderByDesc(Dish::getUpdateTime);
        dishService.page(pageInfo,lqw);
        //對象拷貝
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");

        List<Dish> records = pageInfo.getRecords();
        List<DishDto> list = records.stream().map((item)->{
            DishDto dishDto=new DishDto();

            BeanUtils.copyProperties(item,dishDto);

            Long categoryId = item.getCategoryId();//分類id
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            dishDto.setCategoryName(categoryName);
            return dishDto;
        }).collect(Collectors.toList());

        dishDtoPage.setRecords(list);
        return R.success(dishDtoPage);
    }
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        //log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }
    @GetMapping("{id}")
    public R<DishDto> get(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);
        return R.success("修改成功");
    }
    @DeleteMapping
    public R<String> delete(Long[] ids){
        dishService.deleteByIdWithFlavor(ids);
        return R.success("删除菜品成功");
    }
    @PostMapping("/status/{status}")
    public R<String> status(@PathVariable Integer status,Long[] ids){
       log.info("status:"+status+"   ids:"+ids.length);
       List<Dish> list=new ArrayList<>();
        for (Long id : ids) {
            list.add(new Dish(id, status));
        }
       dishService.updateBatchById(list);
       return R.success("修改成功");
    }
//    @GetMapping("/list")
//    public R<List<Dish>> list(Dish dish){
//        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
//        queryWrapper.eq(StringUtils.isNotEmpty(dish.getCategoryId().toString()),Dish::getCategoryId,dish.getCategoryId());
//        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
//        queryWrapper.eq(Dish::getStatus,1);
//        List<Dish> list = dishService.list(queryWrapper);
//        return R.success(list);
//    }
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){
        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(dish.getCategoryId().toString()),Dish::getCategoryId,dish.getCategoryId());
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        queryWrapper.eq(Dish::getStatus,1);
        List<Dish> list = dishService.list(queryWrapper);
        List<DishDto> dtoList = list.stream().map((item)->{
            DishDto dishDto=new DishDto();
            BeanUtils.copyProperties(item,dishDto);

            Long categoryId = item.getCategoryId();//分類id
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            dishDto.setCategoryName(categoryName);
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> queryWrapper1=new LambdaQueryWrapper<>();
            queryWrapper1.eq(DishFlavor::getDishId,dishId);
            List<DishFlavor> dishFlavors = dishFlavorService.list(queryWrapper1);
            dishDto.setFlavors(dishFlavors);
            return dishDto;
        }).collect(Collectors.toList());
        return R.success(dtoList);
    }
}
           

最後,本文中還會繼續更新。

該項目已經把老師留下的接口大部分都實作,除了登出

分享網盤:

連結:https://pan.baidu.com/s/1ULNDiEtyTzlFzBf5P6i0zA 

提取碼:6666