Springboot接收参数复杂时(如一次接收两张表的参数)怎么操作

问题描述

在SpringBoot代码开发中,有时我们要接收的参数甚至有List数组等复杂的参数,而且还是一次接收两张表的参数我们应该如何解决?


模拟场景

书写外卖软件时,有两张表,第一个表记录菜品为dish表,第二个表记录的是菜品的口味为dish_flavor

而添加菜品时则需要一次性存这两张表,而且口味参数还是List

sql代码:

CREATE TABLE `dish` (
  `id` BIGINT(20) NOT NULL COMMENT '主键',
  `name` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '菜品名称',
  `category_id` BIGINT(20) NOT NULL COMMENT '菜品分类id',
  `price` DECIMAL(10,2) DEFAULT NULL COMMENT '菜品价格',
  `code` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '商品码',
  `image` VARCHAR(200) COLLATE utf8_bin NOT NULL COMMENT '图片',
  `description` VARCHAR(400) COLLATE utf8_bin DEFAULT NULL COMMENT '描述信息',
  `status` INT(11) NOT NULL DEFAULT '1' COMMENT '0 停售 1 起售',
  `sort` INT(11) NOT NULL DEFAULT '0' COMMENT '顺序',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '更新时间',
  `create_user` BIGINT(20) NOT NULL COMMENT '创建人',
  `update_user` BIGINT(20) NOT NULL COMMENT '修改人',
  `is_deleted` INT(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `idx_dish_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品管理';

CREATE TABLE `dish_flavor` (
  `id` BIGINT(20) NOT NULL COMMENT '主键',
  `dish_id` BIGINT(20) NOT NULL COMMENT '菜品',
  `name` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '口味名称',
  `value` VARCHAR(500) COLLATE utf8_bin DEFAULT NULL COMMENT '口味数据list',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '更新时间',
  `create_user` BIGINT(20) NOT NULL COMMENT '创建人',
  `update_user` BIGINT(20) NOT NULL COMMENT '修改人',
  `is_deleted` INT(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品口味关系表';

对应的实体类

/**
 菜品
 */
@Data
public class Dish implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //菜品名称
    private String name;


    //菜品分类id
    private Long categoryId;


    //菜品价格
    private BigDecimal price;


    //商品码
    private String code;


    //图片
    private String image;


    //描述信息
    private String description;


    //0 停售 1 起售
    private Integer status;


    //顺序
    private Integer sort;


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


    //是否删除
    private Integer isDeleted;

}


/**
菜品口味
 */
@Data
public class DishFlavor implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //菜品id
    private Long dishId;


    //口味名称
    private String name;


    //口味数据list
    private String value;


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


    //是否删除
    private Integer isDeleted;

}

前端添加该菜品的参数


解决方案:

这个时候接收参数就比较复杂了,dish是一条数据,而flavors还是多条数据,所以根据这个接收的参数封装一个另外的实体类,来接收这上面的参数。

使用的是DTO,DTO全称为Data Transfer Object,即数据传输对象,一般用于展示层与服务层之间的数据传输。(简单的是使用实体类直接接收,复杂的要另外封装)

一般将这种另外封装的实体类放在单独的放在dto包下面。上面的showOption参数没有用到暂时分装。

由上面可以看出,List类型的参数数据库也是使用的varchar(500)

实体类也是用的String

并且最后参数传回来也是用引号引着的字符串!!

如果是那种批量删除这种业务,一般传dis=1312413,3123123,321321这种以逗号隔开的参数的话。

1、直接Long[]数组接收,没有什么考究的!

2、使用List集合接收时,需要在List型的参数前面加上@RequestParam,因为List是列表,接收时需要处理一下。

3、直接用String接收,然后调用java的split分离成数组,然后遍历即可。

根据参数重新封装一个类如下:

@Data
public class DishDto extends Dish {//继承了Dish说明属性都继承过来了
    //这个就是上面参数的flavors,这个参数比较复杂首先它是一个数组,而且数组里面有两个json,其中json还是name和value
    //所以就是使用了DishFlavor类中的name和value
    private List<DishFlavor> flavors = new ArrayList<>();
}

然后就可以接收到json数据了,进行Controller操作即可

@PostMapping
public R<String> save(@RequestBody DishDto dishDto){
    return null;
}

多张表操作,记得开启事务

首先在启动类加入@EnableTransactionManagement//开启事务的支持

然后你操作的代码方法上加入事务注解,这里我再Service层处理业务,并添加事务!,代码不重要,仅供参考!

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;
    /**
     * 新增菜品,同时保存对应的口味数据
     * @param dishDto
     */
    @Transactional//添加事务
    @Override
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到菜品表dish
        this.save(dishDto);
        //DishFlavor当时是直接保存name和value的值时,其它的可以元数据处理器中自己生成,id也是用雪花算法来生成的,
        //但是DishFlavor类的dishId是null的,所以要把对应dish类的id存入DishFlavor的dishId中
        Long dishId = dishDto.getId();
        for(DishFlavor dishFlavor:dishDto.getFlavors()){
            dishFlavor.setDishId(dishId);
        }
        //保存菜品口味数据到菜品口味表dish_flavor
        dishFlavorService.saveBatch(dishDto.getFlavors());
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值