Java项目-苍穹外卖-Day04

文章目录

  • 公共字段自动填充
  • 增加菜品业务
    • 需求分析
    • 代码开发
      • 文件上传功能
      • 新增菜品开发
  • 菜品分页查询
    • 需求分析
    • 代码开发
      • 易漏点
  • 删除菜品功能开发
    • 需求分析
    • 代码开发
  • 修改菜品业务功能

公共字段自动填充

这些字段在每张表基本都有,手动进行填充效率低,且后期维护更改繁琐
Java项目-苍穹外卖-Day04_第1张图片
Java项目-苍穹外卖-Day04_第2张图片
使用到注解+AOP主要
先答应一个AutoFill注解
Java项目-苍穹外卖-Day04_第3张图片

再定义一个切面类进行通知
Java项目-苍穹外卖-Day04_第4张图片
对应代码
用到了枚举类和反射

package com.sky.aspect;
/**
 *  自定义切面类,实现公共字段自动填充
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    /**
     * 切入点
     */
    //不仅需要符合切入点表达式,且要满足方法上有对应注解
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void auotFillPointCut(){}

    /**
     * 前置通知,在通知中进行公共字段赋值
     */
    @Before("auotFillPointCut()")
    public void autoFill(JoinPoint joinPoint){
        log.info("开始进行公共字段的自动填充...");
        //获取方法上的数据库操作类型(决定是否需修改CreateUser和CreateTime)
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
        AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType value = annotation.value();//获取数据库的操作类型


        //获取方法上的参数--实体参数
        Object[] args = joinPoint.getArgs();
        if (args==null || args.length==0){
            return;
        }
        Object entity=args[0];//可能接收不同实体,因为是公共字段,可能员工,菜品什么的都有,所以用object
        //准备赋值数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //根据当前不同的操作类型,为对应属性进行赋值
        if(value==OperationType.INSERT)
        {
            try {
                //通过反射获取对应的方法
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //再进行赋值
                setCreateTime.invoke(entity,now);
                setUpdateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        else if(value==OperationType.UPDATE) {
            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注解
所以我们在对应mapper文件的insert和update操作做上加上@AutoFill注解并且指定value(操作类型)
Java项目-苍穹外卖-Day04_第5张图片
然后我们就可以把之前service中设置UpdateTime和UpdateUser以及Create的全都可以注释/删除
进行测试
我这里测试过了
提交推送即可

增加菜品业务

需求分析

涉及到我们的菜品分类的回查
还有文件上传图片可以用阿里云的oss实现
Java项目-苍穹外卖-Day04_第6张图片

Java项目-苍穹外卖-Day04_第7张图片
Java项目-苍穹外卖-Day04_第8张图片
Java项目-苍穹外卖-Day04_第9张图片
Java项目-苍穹外卖-Day04_第10张图片
Java项目-苍穹外卖-Day04_第11张图片
Java项目-苍穹外卖-Day04_第12张图片

代码开发

文件上传功能

先开发一个阿里云的服务
Java项目-苍穹外卖-Day04_第13张图片
先写配置文件,来写我们的域名,bucket名,秘钥id和密码
Java项目-苍穹外卖-Day04_第14张图片
第三方bean,写个配置类
配置上对应的参数
Java项目-苍穹外卖-Day04_第15张图片
再写Commoncontroller
Java项目-苍穹外卖-Day04_第16张图片

@RestController
@RequestMapping("/admin/common")
@Api(tags = "通用接口")
@Slf4j
public class CommonController {
    @Autowired
    private AliOssUtil aliOssUtil;

    @ApiOperation("文件上传")
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);

        try {
            //获取原始文件名
            String originalFilename = file.getOriginalFilename();
            //截取原始文件名后缀 xxx.jpg
            String substring = originalFilename.substring(originalFilename.lastIndexOf('.'));
            String uuid = UUID.randomUUID().toString();
            //构造新文件名
            String name=uuid+substring;

            String filePath = aliOssUtil.upload(file.getBytes(), name);//返回值为文件请求路径

                return Result.success(filePath);

        } catch (IOException e) {
            log.error("文件上传失败:{}",e);
        }


        return Result.error(MessageConstant.UPLOAD_FAILED);
    }

}

这样就可以了,完成文件上传操作,用到了阿里云oss,不知道怎么用可以看一下我之前的文件上传博客
把对应权限改为公开权限就可以在别的地方看到对应图片

新增菜品开发

controller

@RestController
@RequestMapping("/admin/dish")
@Slf4j
@Api(tags = "菜品相关接口")
public class DishController {
    @Autowired
    private DishService dishService;

    @PostMapping
    @ApiOperation("新增菜品")
    public Result save(@RequestBody DishDTO dishDTO){
        log.info("新增菜品:{}",dishDTO);
        dishService.savewithFlavor(dishDTO);
        return Result.success();
        }
}

Java项目-苍穹外卖-Day04_第17张图片
Service

@Service
@Slf4j
public class DishServiceImpl implements DishService {
    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    /**
     * 新增菜品和对应的口味数据
     * @param dishDTO
     */
    @Transactional//事务注解,因为有两次操作的,一次修改菜品表,一次是口味表
    public void savewithFlavor(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        //向菜品表插入1条数据
        dishMapper.insert(dish);
        //获取insert语句生产的主键值
        Long id = dish.getId();
        //向口味表插入n条数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if(flavors != null && flavors.size() > 0) {

            for (DishFlavor flavor:flavors
                 ) {
                flavor.setDishId(id);
            }
        dishFlavorMapper.insertBatch(flavors);

        }
    }
}

Java项目-苍穹外卖-Day04_第18张图片
解释一下,分开两个表插入的其实是,所以我们要加上@Transactional的注解,进行一个事务操作,还要创建两个mapper

DishMapper

@Mapper
public interface DishMapper {

    /**
     * 根据分类id查询菜品数量
     * @param categoryId
     * @return
     */
    @Select("select count(id) from dish where category_id = #{categoryId}")
    Integer countByCategoryId(Long categoryId);

    @AutoFill(value = OperationType.INSERT)
    void insert(Dish dish);

}

对应xml


DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into dish (name,category_id,price,image,description,create_time,update_time,create_user,update_user,status)
        values
        (#{name},#{categoryId},#{price},#{image},#{description},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})
    insert>

mapper>

DishFlavorMapper

@Mapper
public interface DishFlavorMapper {
    /**
     * 批量插入口味数据
     * @param flavors
     */
    @AutoFill(value = OperationType.INSERT)
    void insertBatch(List<DishFlavor> flavors);
}

对应xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.DishFlavorMapper">
    <insert id="insertBatch">
        insert into dish_flavor(dish_id,name,value) values
        <foreach collection="flavors" item="df" separator=",">
            (#{df.dishId},#{df.name},#{df.value})
        </foreach>
    </insert>
</mapper>

然后就是前后端联调
我联调成功了
记得在insert操作上加@AutoFill不然不会自动加入创建人那些公共字段

菜品分页查询

需求分析

Java项目-苍穹外卖-Day04_第19张图片
Java项目-苍穹外卖-Day04_第20张图片
Java项目-苍穹外卖-Day04_第21张图片

代码开发

controller
Java项目-苍穹外卖-Day04_第22张图片
service
Java项目-苍穹外卖-Day04_第23张图片
mapper+xml
在这里插入图片描述
Java项目-苍穹外卖-Day04_第24张图片
测试成功
主要看能不能显示出菜品名称

易漏点

dish表里无菜品分类名称这一个字段的,需要返回DishVO对象
但有category_id这个字段,可以在category里面查到
需要从category里查
这里设计到多表查询了,而且是以一个表的字段匹配另一个表
这里直接用了左外连接进行查询

删除菜品功能开发

需求分析

注意点
两点
1.在套餐内菜品不能直接删除
2.删除对应的菜品对应的口味表也要删除
Java项目-苍穹外卖-Day04_第25张图片
Java项目-苍穹外卖-Day04_第26张图片
Java项目-苍穹外卖-Day04_第27张图片
Java项目-苍穹外卖-Day04_第28张图片

代码开发

controller
Java项目-苍穹外卖-Day04_第29张图片
service
Java项目-苍穹外卖-Day04_第30张图片
对应涉及到根据ID查询的mapper就不放图片了,也用不到xml文件
像根据id查询菜品,根据id删除菜品,还有口味表中的根据菜品id删除口味都简单,直接注解实现即可

mapper
因为要根据菜品的id查询套餐的id
setmealmapper

Java项目-苍穹外卖-Day04_第31张图片

Java项目-苍穹外卖-Day04_第32张图片
测试
自己测试试试
根据对应的业务规则

修改菜品业务功能

设计根据id回显和修改操作
不仅涉及菜品表还涉及菜品口味表
controller
Java项目-苍穹外卖-Day04_第33张图片
service
id获取菜品信息
Java项目-苍穹外卖-Day04_第34张图片
修改菜品信息
注意:这里修改口味表情况比较多,我们就用事务注解+删除原口味+新增口味的方法完成
Java项目-苍穹外卖-Day04_第35张图片
mapper
用到的基本都是之前定义的
就新增这个修改菜品基本信息的
Java项目-苍穹外卖-Day04_第36张图片

你可能感兴趣的:(项目记录,java,开发语言)