栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

瑞吉外卖:黑马程序员

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

瑞吉外卖:黑马程序员

这是第二章 没有看过的可以点超链接跳转第一篇
分页查询

由页面得知请求方法是Get请求 请求路径是page 参数是 page和pageSize
页面上边有一个查询按钮 得知 还有一个参数name
我们使用Mybatis-Plus给我们的分页查询Page

 @GetMapping("page")
    public R page(int page,int pageSize,String name){
        //分页构造器
        Page pageInfo = new Page(page,pageSize);
        //条件构造器
        LambdaQueryWrapper queryWrapper=new LambdaQueryWrapper<>();
        //这里使用模糊查询**like** 使用等值查询eq需要把所有都打出来
        queryWrapper.like(!StringUtils.isEmpty(name),Employee::getName,name);
        //根据修改时间降序排列
        queryWrapper.orderByDesc(Employee::getUpdateTime);
        //执行查询
        employeeService.page(pageInfo,queryWrapper);
        return R.success(pageInfo);
    }

还需要一个MP提供的分页插件

@Configuration
public class MybatisPlusConfig {
 @Bean
 public MybatisPlusInterceptor mybatisPlusInterceptor() {
     MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
     interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
     return interceptor;
     //里边是DbType.MYSQL自己的数据库 我的是Mysql 
 }
}

修改员工信息 修改status字段
根据id修改状态

   @PutMapping                 //本来只是更新status字段 这个把员工所有都更新了
 public R update(@RequestBody Employee employee,HttpSession session){
     Long id = (Long) session.getAttribute("employee");
     employee.setUpdateTime(LocalDateTime.now());
     employee.setUpdateUser(id);
     employeeService.updateById(employee);
     return R.success("成功");
 }

当我们点击禁用按钮时 前端返回我们的用户id和我们传的id不一致 js对Long型的数字只能精确到前16位 而我们传递过去的数字有19位 我们可以将服务端响应的json进行处理,将Long型的数据统一转换为String
实现步骤 提供消息转换器JacksonObjectMapper 再WebMvc中扩展extendMessageConverters

 @Override
   protected void extendMessageConverters(List> converters) {
       log.info("消息转换器");
       //创建一个新的消息转换器
       MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
       //设置对象转换器 底层使用jackson将java转换为json
       converter.setObjectMapper(new JacksonObjectMapper());
       //将上面的消息转换器追加到mvc框架的转换器中  index是把我们自己的转换器放到最前边 优先使用
       converters.add(0, converter);
   }


这是springMVC的8个消息转换器

编辑员工
请求路径是restful风格

@GetMapping("/{id}")
   public R getByid(@PathVariable Long id){
       Employee byId = employeeService.getById(id);
       if (byId!=null){
           return R.success(byId);
       }
       return R.error("出现了错误");
   }

优化

create_time
update_time
create_user
update_user

这四个公共字段 每次创建或者修改的时候都需要我们去设置 又没有方法让他自己填充呢
答:当然有了 MP给我们封装了自动填充 只需要在字段上加上

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

在创建的时候或者更新的时候加上这个注解**@TableField** 表字段 自动填充的策略
我们编写一个类并实现MetaObjectHandler

//当第一次创建时
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("createUser",BaseContext.getThreadLocal());
        metaObject.setValue("updateUser",BaseContext.getThreadLocal());
        metaObject.setValue("updateTime",LocalDateTime.now());
    }

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

当我们创建和修改时 都需要让他自动设置。还有一个问题 我们知道 像createUser updateUser是从id中获取 那id怎么来呢 聪明的小伙伴说从session中获取 我们没有办法从MetaObjectHandler获取session对象 所以使用ThreadLocal

ThreadLocal不是Thread 而是它的一个局部变量 当使用ThreadLocal维护变量时 都会为该线程提供独立的变量副本 而不会影响其他线程所对应的副本

我们可以在过滤器中拿到id 并使用ThreadLocal的set方法设置当前的用户id,然后再updateUser调用get方法获取
我们先创建一个ThreadLocal封装工具类

//基于ThreadLocal封装工具了 保存获取用户id
public class BaseContext {
    private static ThreadLocal threadLocal=new ThreadLocal<>();

    
    public static void setThreadLocal(Long  id) {
        threadLocal.set(id);
    }

    
    public static Long getThreadLocal() {
        return threadLocal.get();
    }

然后再Filter中设置

Long employee = (Long) request.getSession().getAttribute("employee");
        BaseContext.setThreadLocal(employee);

把从session中获取的id放入设置好的ThreadLocal中
然后从MyMetaObjectHandler中调用BaseContext.getThreadLocal()获取

========================================================

第二大模块 新增分类 Category 使用MybatisX创建 实体类 Category Mapper、CategoryService、CategoryServiceImpl、 CategoryController

由前端得知 类型是json类型 请求方式post 请求路径没有

@PostMapping
    public R save(@RequestBody Category category) {
        categoryService.save(category);
        return R.success("成功");
    }    

Category的分页查询
上边我们写了一个分页查询

@GetMapping("page")
    public R page(int page,int pageSize){
    //分页构造器
        Page pageInfo = new Page<>(page, pageSize);
        //构造条件
        LambdaQueryWrapper queryWrapper=new LambdaQueryWrapper<>();
        //根据排序的降序排列
        queryWrapper.orderByAsc(Category::getSort);
        //以及执行查询
        categoryService.page(pageInfo,queryWrapper);
        return R.success(pageInfo);
    }

分类管理的删除按钮

 @DeleteMapping
    public R delete(@PathVariable Long id){
        categoryService.removeById(id);
        return R.success("成功");
    }

优化 我们点击删除按钮就会删除掉所有 也不知道分类下有没有菜品或者套餐
我们在service中定义一个接口

void remove(Long id);

在Impl中实现

   public void remove(Long id) {
       //添加查询条件
      LambdaQueryWrapper queryWrapper1=new LambdaQueryWrapper();
      queryWrapper1.eq(Dish::getCategoryId,id);
                               //统计
       int count = dishService.count(queryWrapper1);
       if (count>0){
           throw new CustomException("当前分类下关联了菜品 不能删除");

         //关联菜品 抛出一个业务异常
       }
       //查询是否关联了套餐  如果关联了套餐 就
       LambdaQueryWrapper queryWrapper2=new LambdaQueryWrapper();
       queryWrapper2.eq(Setmeal::getCategoryId,id);
       int count1 = setmealService.count();
       setmealService.count(queryWrapper2);
       if (count1>0){
           throw new CustomException("当前分类下关联了套餐 不能删除");
       }
       super.removeById(id);
   } 

我们需要定义一个全局异常 继承于RuntimeException

public CustomException(String msg){
        super(msg);
    }

并且在GlobaExceptionHandler处理我们的自定义异常

 @ExceptionHandler(RuntimeException.class)
    public R exception(RuntimeException e) {
        return R.error(e.getMessage());
    } 

我们在控制层中从新调用remove方法

 @DeleteMapping
    public R delete(@PathVariable Long id){
        categoryService.remove(id);
        //categoryService.removeById(id);
        return R.success("成功");
    }  

这样删除就完成了
分类管理中的修改按钮

  @PutMapping
    public R update(@RequestBody Category category){
        categoryService.updateById(category);
        return R.success("成功");
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879854.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号