谷粒商城-day10-品牌关联分类实现

引入分页插件

目前无分页数据

image-20220522181600205

引入分页插件

package com.zhouzhou.gulimall.product.config;


import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement // 开启使用事务
@MapperScan("com.zhouzhou.gulimall.product.dao")
public class MybatisConfig {

    // 引入分页插件
    // 旧版
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
         paginationInterceptor.setOverflow(true);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
         paginationInterceptor.setLimit(1000);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

image-20210224171413460

品牌管理

品牌的模糊查询接口

@Override
public PageUtils queryPage(Map<String, Object> params) {
    //1. 获取 key
    String key = (String) params.get("key");
    QueryWrapper<BrandEntity> queryWrapper = new QueryWrapper<>();
    if (!StringUtils.isEmpty(key)){
        queryWrapper.eq("brand_id", key).or().like("name", key);
    }
    IPage<BrandEntity> page = this.page(
            new Query<BrandEntity>().getPage(params),
            queryWrapper
    );
    return new PageUtils(page);
}

image-20210224171831295

测试

添加有用的数据

common 中导入 brand-select 和 category-cascade 两个组件

覆盖 brand 的两个vue 文件,下一小节实现关联分类的功能

关联分类实现

品牌和分类是多对多的关系

image-20210224212012980

获得与品牌关联的分类

/**
     * 获取当前品牌关联的所有分类列表
     */
    @GetMapping("/catelog/list")
    public R list(@RequestParam("brandId") Long brandId){
        List<CategoryBrandRelationEntity> data = categoryBrandRelationService.list(
                new QueryWrapper<CategoryBrandRelationEntity>().eq("brand_id", brandId));

        return R.ok().put("data", data);
    }
image-20210225150950036

新增品牌与分类关联关系

image-20210225151212281

考虑到电商系统,没有设计外键,这里在存放id的时候也存放了名字,生成的代码中没有名字,需要重写

// CategoryBrandRelationController
/**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody CategoryBrandRelationEntity categoryBrandRelation){
		categoryBrandRelationService.saveDetail(categoryBrandRelation);

        return R.ok();
    }

// CategoryBrandRelationServiceImpl
 @Override
    public void saveDetail(CategoryBrandRelationEntity categoryBrandRelation) {
        Long brandId = categoryBrandRelation.getBrandId();
        Long catelogId = categoryBrandRelation.getCatelogId();
//        1.查询详细名字
        BrandEntity brandEntity = brandDao.selectById(brandId);
        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);

        categoryBrandRelation.setBrandName(brandEntity.getName());
        categoryBrandRelation.setCatelogName(categoryEntity.getName());

        this.save(categoryBrandRelation);
    }
image-20210225151741391 image-20210225151757865

冗余数据的级联更新

冗余设计需要实时更新

image-20210225154212945 image-20210225154153849

前端这里需要添加一个依赖

npm install pubsub-js@1.8.0 --save

并且在 main 函数挂载

import PubSub from "pubsub-js"
Vue.prototype.PubSub = PubSub;

brand 冗余 保证一直

// file: BrandController
    /**
     * 修改
     */
    @RequestMapping("/update")
//     @RequiresPermissions("product:brand:update")
    public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
        brandService.updateDeatil(brand);

        return R.ok();
    }

// file: BrandServiceImpl
@Override
public void updateDeatil(BrandEntity brand) {
    // 保证冗余字段的数据一致
    this.updateById(brand);
    if (!StringUtils.isEmpty(brand.getName())) {
        // 同步更新其他关联表中的数据
        categoryBrandRelationService.updateBrand(brand.getBrandId(), brand.getName());
        //TODO 更新其他关联
    }
}

// file: CategoryBrandRelationServiceImpl
@Override
public void updateBrand(Long brandId, String name) {
    CategoryBrandRelationEntity relationEntity = new CategoryBrandRelationEntity();
    relationEntity.setBrandId(brandId);
    relationEntity.setBrandName(name);
    this.update(relationEntity, new QueryWrapper<CategoryBrandRelationEntity>().eq("brand_id", brandId));
}

这里测试修改品牌名,关联分类中显示的品牌名也会改变

image-20220523135201572 image-20220523135144223

同理,分类修改时也需要同步修改所有引用的中间表

这里改成在dao层实现

// file: CategoryController
 /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody CategoryEntity category) {
        categoryService.updateCascade(category);

        return R.ok();
    }

/**
     * 级联更新所有关联数据
     *
     * @param category
     */
    @Override
    public void updateCascade(CategoryEntity category) {
        this.updateById(category);
        this.baseMapper.updateCategory(category.getCatId(), category.getName());
    }

// 这里前面都一样,但是到了CategoryBrandRelationServiceImpl 的时候,在mapper层进行重写
@Override
public void updateCategory(Long catId, String name) {
    this.baseMapper.updateCategory(catId, name);
}

@Mapper
public interface CategoryBrandRelationDao extends BaseMapper<CategoryBrandRelationEntity> {

    void updateCategory(@Param("catId") Long catId, @Param("name") String name);
}
<update id="updateCategory">
    UPDATE `pms_category_brand_relation` SET catelog_name=#{name} where catelog_id=#{catId}
</update>

一个用的 QueryWrapper 一个用的 mapper

这里测试修改分类名称

image-20210225164641276 image-20210225164649288

最后 加上事务控制

@Override
@Transactional
public void updateDeatil(BrandEntity brand) {
    // 保证冗余字段的数据一致
    this.updateById(brand);
    if (!StringUtils.isEmpty(brand.getName())) {
        // 同步更新其他关联表中的数据
        categoryBrandRelationService.updateBrand(brand.getBrandId(), brand.getName());

        //TODO 更新其他关联
    }
}
@Transactional
@Override
public void updateCascade(CategoryEntity category) {
    this.updateById(category);
    categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}

也是由于 MyabtisConfig 里面添加了事务相关的配置

总结

品牌管理这里重点在于冗余数据一致性,总结起来实现总共有两个点:

  • 中间表带上两张表详细字段
image-20220527144542503
  • 两张关联的表在修改和新增的时候都需要写冗余的中间表

这里如果不设计冗余表,每次查询关联数据的时候都需要使用 join 查询

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值