联表删除操作

在复杂的项目中,往往需要用到联表操作才能进行功能实现,而联表操作删除难度要比单表删除大的多,不仅是存在同时删除两张表中的内容,也需要考虑到表中的数据所存在的状态,是否能够直接删除。

以下案例供参考:

entity:

/**
 * 套餐菜品关系
 */
@Data
public class SetmealDish implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //套餐id
    private Long setmealId;


    //菜品id
    private Long dishId;


    //菜品名称 (冗余字段)
    private String name;

    //菜品原价
    private BigDecimal price;

    //份数
    private Integer copies;


    //排序
    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 Setmeal implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //分类id
    private Long categoryId;


    //套餐名称
    private String name;


    //套餐价格
    private BigDecimal price;


    //状态 0:停用 1:启用
    private Integer status;


    //编码
    private String code;


    //描述信息
    private String description;


    //图片
    private String image;


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

}

由于整体功能都是在操作两张表,为了操作方便,增加了个dto类,它继承了Setmeal同时把前面的SetmealDish作为其中一个属性加入进去。

@Data
public class SetmealDto extends Setmeal {

    private List setmealDishes;

    private String categoryName;
}

service层操作:

操作逻辑:

(1)先根据id找到需要删除的数据,判断其状态是否可以直接删除

(2)如果不能删除,直接返回给前段不能删除

(3)如果可以删除,先删除其中一张表中的数据

(4)在根据其中的联表键,删除另一张表中的数据

注意: 方法上需要添加@Transactional注解,并在启动类上开始这个注解,目的是所有的操作若全部执行成功,则实现最终效果,如果没有全部执行成功,则回滚,返回到最初状态

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl implements SetmealService {

 
    /**
     * 删除套餐,同时需要删除套餐和菜品的关联数据
     * @param ids
     */
    @Transactional
    public void removeWithDish(List ids) {
        //select count(*) from setmeal where id in (1,2,3) and status = 1
        //查询套餐状态,确定是否可用删除
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
        queryWrapper.in(Setmeal::getId,ids);
        queryWrapper.eq(Setmeal::getStatus,1);

        int count = this.count(queryWrapper);
        if(count > 0){
            //如果不能删除,抛出一个业务异常
            throw new CustomException("套餐正在售卖中,不能删除");
        }

        //如果可以删除,先删除套餐表中的数据---setmeal
        this.removeByIds(ids);

        //delete from setmeal_dish where setmeal_id in (1,2,3)
        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids);
        //删除关系表中的数据----setmeal_dish
        setmealDishService.remove(lambdaQueryWrapper);
    }
}

controller层调用service方法即可

你可能感兴趣的:(java,数据库,spring)