乐优商城学习笔记六-商品管理

1.SPU和SKU数据结构

规格确定以后,就可以添加商品了,先看下数据库表

1.1.SPU表

1.1.1.表结构

SPU表:

CREATE TABLE `tb_spu` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'spu id',
  `title` varchar(255) NOT NULL DEFAULT '' COMMENT '标题',
  `sub_title` varchar(255) DEFAULT '' COMMENT '子标题',
  `cid1` bigint(20) NOT NULL COMMENT '1级类目id',
  `cid2` bigint(20) NOT NULL COMMENT '2级类目id',
  `cid3` bigint(20) NOT NULL COMMENT '3级类目id',
  `brand_id` bigint(20) NOT NULL COMMENT '商品所属品牌id',
  `saleable` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否上架,0下架,1上架',
  `valid` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否有效,0已删除,1有效',
  `create_time` datetime DEFAULT NULL COMMENT '添加时间',
  `last_update_time` datetime DEFAULT NULL COMMENT '最后修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=208 DEFAULT CHARSET=utf8 COMMENT='spu表,该表描述的是一个抽象的商品,比如 iphone8';

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

与我们前面分析的基本类似,但是似乎少了一些字段,比如商品描述。

我们做了表的垂直拆分,将SPU的详情放到了另一张表:tb_spu_detail

CREATE TABLE `tb_spu_detail` (
  `spu_id` bigint(20) NOT NULL,
  `description` text COMMENT '商品描述信息',
  `specifications` varchar(3000) NOT NULL DEFAULT '' COMMENT '全部规格参数数据',
  `spec_template` varchar(1000) NOT NULL COMMENT '特有规格参数及可选值信息,json格式',
  `packing_list` varchar(1000) DEFAULT '' COMMENT '包装清单',
  `after_service` varchar(1000) DEFAULT '' COMMENT '售后服务',
  PRIMARY KEY (`spu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这张表中的数据都比较大,为了不影响主表的查询效率我们拆分出这张表。

需要注意的是这两个字段:specifications和spec_template。

1.1.2.spu中的规格参数

前面讲过规格参数与商品分类绑定,一个分类下的所有SPU具有类似的规格参数。SPU下的SKU可能会有不同的规格参数,因此我们计划是这样:

  • SPU中保存全局的规格参数信息。
  • SKU中保存特有规格参数。

以手机为例,品牌、操作系统等肯定是全局属性,内存、颜色等肯定是特有属性。

当你确定了一个SPU,比如小米的:红米4X

全局属性举例:

品牌:小米
型号:红米4X

 
 
  • 1
  • 2

特有属性举例:

颜色:[香槟金, 樱花粉, 磨砂黑]
内存:[2G, 3G]
机身存储:[16GB, 32GB]

 
 
  • 1
  • 2
  • 3

来看下我们的 表如何存储这些信息:

1.1.2.1.specifications字段

首先是specifications,其中保存全部规格参数信息,因此也是一个json格式:

整体来看:

1526262279963

展开一组来看

1526262389233

可以看到,与规格参数表中的模板相比,最大的区别就是,这里指定了具体的值,因为商品确定了,其参数值肯定也确定了。

特有属性

刚才看到的是全局属性,那么特有属性在这个字段中如何存储呢?

1526263214087

我们发现特有属性也是有的,但是,注意看这里是不确定具体值的,因为特有属性只有在SKU中才能确定。这里只是保存了options,所有SKU属性的可选项。

在哪里会用到这个字段的值呢,商品详情页的规格参数信息中:

1526267700765

1.1.2.2.spec_template字段

既然specifications已经包含了所有的规格参数,那么为什么又多出了一个spec_template呢?

里面又有哪些内容呢?

来看数据格式:

1526267952827

可以看出,里面只保存了规格参数中的特有属性,而且格式进行了大大的简化,只有属性的key,和待选项。

为什么要冗余保存一份?

因为很多场景下我们只需要查询特有规格属性,如果放在一起,每次查询再去分离比较麻烦。

比如,商品详情页展示可选的规格参数时:

1526267828817

2.页面实现

2.1.页面实现代码

<template>
  <v-card>
    <v-card-title>
      <v-btn color="primary" @click="addGoods">新增商品</v-btn>
      <!--搜索框,与search属性关联-->
      <v-spacer/>
      <v-text-field label="输入关键字搜索" v-model.lazy="search" append-icon="search" hide-details/>
    </v-card-title>
    <v-divider/>
    <v-data-table
      :headers="headers"
      :items="goodsList"
      :search="search"
      :pagination.sync="pagination"
      :total-items="totalGoods"
      :loading="loading"
      class="elevation-1"
    >
      <template slot="items" slot-scope="props">
        <td>{{ props.item.id }}</td>
        <td class="text-xs-center">{{ props.item.title }}</td>
        <td class="text-xs-center">{{props.item.cname}}</td>
        <td class="text-xs-center">{{ props.item.bname }}</td>
        <td class="justify-center layout">
          <v-btn color="info" @click="editGoods(props.item)">编辑</v-btn>
          <v-btn color="warning">删除</v-btn>
          <v-btn >下架</v-btn>
        </td>
      </template>
    </v-data-table>
    <!--弹出的对话框-->
    <v-dialog max-width="500" v-model="show" persistent>
      <v-card>
        <!--对话框的标题-->
        <v-toolbar dense dark color="primary">
          <v-toolbar-title>{{isEdit ? '修改' : '新增'}}商品</v-toolbar-title>
          <v-spacer/>
          <!--关闭窗口的按钮-->
          <v-btn icon @click="closeWindow"><v-icon>close</v-icon></v-btn>
        </v-toolbar>
        <!--对话框的内容,表单-->
        <v-card-text class="px-5">
          <my-goods-form :oldGoods="oldGoods" />
        </v-card-text>
      </v-card>
    </v-dialog>
  </v-card>
</template>

<script>
// 导入自定义的表单组件
import MyGoodsForm from ‘./MyGoodsForm’

export default {
name: “my-goods”,
data() {
return {
search: ‘’, // 搜索过滤字段
totalGoods: 0, // 总条数
goodsList: [], // 当前页品牌数据
loading: true, // 是否在加载中
pagination: {}, // 分页信息
headers: [
{text: ‘id’, align: ‘center’, value: ‘id’},
{text: ‘标题’, align: ‘center’, sortable: false, value: ‘title’},
{text: ‘商品分类’, align: ‘center’, sortable: false, value: ‘cname’},
{text: ‘品牌’, align: ‘center’, value: ‘bname’, sortable: false,},
{text: ‘操作’, align: ‘center’, sortable: false}
],
show: false,// 控制对话框的显示
oldGoods: {}, // 即将被编辑的商品信息
isEdit: false, // 是否是编辑
}
},
mounted() { // 渲染后执行
// 查询数据
this.getDataFromServer();
},
watch: {
pagination: { // 监视pagination属性的变化
deep: true, // deep为true,会监视pagination的属性及属性中的对象属性变化
handler() {
// 变化后的回调函数,这里我们再次调用getDataFromServer即可
this.getDataFromServer();
}
},
search: { // 监视搜索字段
handler() {
this.getDataFromServer();
}
}
},
methods: {
getDataFromServer() { // 从服务的加载数的方法。
// 发起请求
this.$http.get("/item/spu/page", {
params: {
key: this.search, // 搜索条件
page: this.pagination.page,// 当前页
rows: this.pagination.rowsPerPage,// 每页大小
sortBy: this.pagination.sortBy,// 排序字段
desc: this.pagination.descending// 是否降序
}
}).then(resp => { // 这里使用箭头函数
this.goodsList = resp.data.items;
this.totalGoods = resp.data.total;
// 完成赋值后,把加载状态赋值为false
this.loading = false;
})
},
addGoods() {
// 修改标记
this.isEdit = false;
// 控制弹窗可见:
this.show = true;
// 把oldBrand变为null
this.oldBrand = null;
},
editGoods(oldGoods){
// 修改标记
this.isEdit = true;
// 控制弹窗可见:
this.show = true;
// 获取要编辑的brand
this.oldGoods = oldGoods;
},
closeWindow(){
// 重新加载数据
this.getDataFromServer();
// 关闭窗口
this.show = false;
}
},
components:{
MyGoodsForm
}
}
</script>

<style scoped>

</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

主要的改动点:

  • 页面的v-data-table中的属性绑定修改。items指向goodsList,totalItems指向totalGoods

  • 页面渲染的字段名修改:字段改成商品的SPU字段:id、title,cname(商品分类名称),bname(品牌名称)

  • data属性修改了以下属性:

    • goodsList:当前页商品数据
    • totalGoods:商品总数
    • headers:头信息,需要修改头显示名称
    • oldGoods:准备要修改的商品
  • 加载数据的函数:getDataFromServer,请求的路径进行了修改,另外去除了跟排序相关的查询。SPU查询不排序

  • 新增商品的事件函数:清除了一些数据查询接口,只保留弹窗

查看效果:

1526272476614

2.3.后台提供接口

页面已经准备好,接下来在后台提供分页查询SPU的功能:

实体类

spu

@Data
@Table(name = "tb_spu")
public class Spu {
    @Id
    @KeySql(useGeneratedKeys = true)
//    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long brandId;
    private Long cid1;// 1级类目
    private Long cid2;// 2级类目
    private Long cid3;// 3级类目
    private String title;// 标题
    private String subTitle;// 子标题
    private Boolean saleable;// 是否上架
    private Boolean valid;// 是否有效,逻辑删除用
    private Date createTime;// 创建时间
    private Date lastUpdateTime;// 最后修改时间
    @Transient
    private String cname;
    @Transient
    private String bname;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

spu详情表

@Table(name="tb_spu_detail")
public class SpuDetail {
    @Id
    private Long spuId;// 对应的SPU的id
    private String description;// 商品描述
    private String specTemplate;// 商品特殊规格的名称及可选值模板
    private String specifications;// 商品的全局规格属性
    private String packingList;// 包装清单
    private String afterService;// 售后服务
    // 省略getter和setter
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

controller

先分析:

  • 请求方式:GET

  • 请求路径:/spu/page

  • 请求参数:

    • page:当前页
    • rows:每页大小
    • key:过滤条件
    • saleable:上架或下架
  • 返回结果:商品SPU的分页信息。

    • 要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,怎么办?

      我们可以在spu类,拓展cname和bname属性,

      @Data
      @Table(name = "tb_spu")
      public class Spu {
    
      <span class="token annotation punctuation">@Transient</span>
      <span class="token keyword">private</span> String cname<span class="token punctuation">;</span>
      <span class="token annotation punctuation">@Transient</span>
      <span class="token keyword">private</span> String bname<span class="token punctuation">;</span>
    

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

代码

@RestController
public class GoodsController {
<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> GoodsService goodsService<span class="token punctuation">;</span>
<span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">"/spu/page"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> ResponseEntity<span class="token operator">&lt;</span>PageResult<span class="token generics function"><span class="token punctuation">&lt;</span>Spu<span class="token punctuation">&gt;</span></span><span class="token operator">&gt;</span> <span class="token function">querySpuByPage</span><span class="token punctuation">(</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"page"</span><span class="token punctuation">,</span>defaultValue <span class="token operator">=</span> <span class="token string">"1"</span><span class="token punctuation">)</span> Integer page<span class="token punctuation">,</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"rows"</span><span class="token punctuation">,</span>defaultValue <span class="token operator">=</span> <span class="token string">"5"</span><span class="token punctuation">)</span> Integer rows<span class="token punctuation">,</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"sortBy"</span><span class="token punctuation">,</span> required <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> String sortBy<span class="token punctuation">,</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"desc"</span><span class="token punctuation">,</span> defaultValue <span class="token operator">=</span> <span class="token string">"false"</span><span class="token punctuation">)</span> Boolean desc<span class="token punctuation">,</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"key"</span><span class="token punctuation">,</span>required <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> String key<span class="token punctuation">,</span>
        <span class="token annotation punctuation">@RequestParam</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"saleable"</span><span class="token punctuation">,</span>defaultValue <span class="token operator">=</span> <span class="token string">"true"</span><span class="token punctuation">)</span> Boolean saleable


<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> ResponseEntity<span class="token punctuation">.</span><span class="token function">ok</span><span class="token punctuation">(</span>goodsService<span class="token punctuation">.</span><span class="token function">querySpuByPage</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span>rows<span class="token punctuation">,</span>saleable<span class="token punctuation">,</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

service

所有商品相关的业务(包括SPU和SKU)放到一个业务下:GoodsService。

@Service
public class GoodsService {
    @Autowired
    private SpuMapper spuMapper;
<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> SpuDetailMapper spuDetailMapper<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> CategoryService categoryService<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> BrandService brandService<span class="token punctuation">;</span>

<span class="token keyword">public</span> PageResult<span class="token generics function"><span class="token punctuation">&lt;</span>Spu<span class="token punctuation">&gt;</span></span> <span class="token function">querySpuByPage</span><span class="token punctuation">(</span>Integer page<span class="token punctuation">,</span> Integer rows<span class="token punctuation">,</span> Boolean saleable<span class="token punctuation">,</span> String key<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//分页</span>
    PageHelper<span class="token punctuation">.</span><span class="token function">startPage</span><span class="token punctuation">(</span>page<span class="token punctuation">,</span>rows<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//过滤</span>
    Example example <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Example</span><span class="token punctuation">(</span>Spu<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    Example<span class="token punctuation">.</span>Criteria criterion <span class="token operator">=</span> example<span class="token punctuation">.</span><span class="token function">createCriteria</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//搜索字段过滤</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>StringUtils<span class="token punctuation">.</span><span class="token function">isNotBlank</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        criterion<span class="token punctuation">.</span><span class="token function">andLike</span><span class="token punctuation">(</span><span class="token string">"title"</span><span class="token punctuation">,</span><span class="token string">"%"</span><span class="token operator">+</span>key<span class="token operator">+</span><span class="token string">"%"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//上下架过滤</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>saleable <span class="token operator">!=</span> null<span class="token punctuation">)</span><span class="token punctuation">{</span>
        criterion<span class="token punctuation">.</span><span class="token function">orEqualTo</span><span class="token punctuation">(</span><span class="token string">"saleable"</span><span class="token punctuation">,</span>saleable<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">//排序</span>
    example<span class="token punctuation">.</span><span class="token function">setOrderByClause</span><span class="token punctuation">(</span><span class="token string">"last_update_time DESC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">//查询</span>
    List<span class="token generics function"><span class="token punctuation">&lt;</span>Spu<span class="token punctuation">&gt;</span></span> spus <span class="token operator">=</span> spuMapper<span class="token punctuation">.</span><span class="token function">selectByExample</span><span class="token punctuation">(</span>example<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//判断</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>CollectionUtils<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>spus<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">LyException</span><span class="token punctuation">(</span>ExceptionEnum<span class="token punctuation">.</span>GOODS_NOT_FOOD<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span>
    <span class="token comment">//解析分类和品牌的名称</span>
    <span class="token function">loadCategoryAndBrandName</span><span class="token punctuation">(</span>spus<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//解析分页结果</span>
    PageInfo<span class="token generics function"><span class="token punctuation">&lt;</span>Spu<span class="token punctuation">&gt;</span></span> info <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PageInfo</span><span class="token operator">&lt;</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>spus<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">PageResult</span><span class="token operator">&lt;</span><span class="token operator">&gt;</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span><span class="token function">getTotal</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>spus<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">loadCategoryAndBrandName</span><span class="token punctuation">(</span>List<span class="token generics function"><span class="token punctuation">&lt;</span>Spu<span class="token punctuation">&gt;</span></span> spus<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span>Spu spu<span class="token operator">:</span>spus<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token comment">//处理分类名称</span>
        List<span class="token generics function"><span class="token punctuation">&lt;</span>String<span class="token punctuation">&gt;</span></span> names <span class="token operator">=</span> categoryService<span class="token punctuation">.</span><span class="token function">queryByIds</span><span class="token punctuation">(</span>Arrays<span class="token punctuation">.</span><span class="token function">asList</span><span class="token punctuation">(</span>spu<span class="token punctuation">.</span><span class="token function">getCid1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> spu<span class="token punctuation">.</span><span class="token function">getCid2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> spu<span class="token punctuation">.</span><span class="token function">getCid3</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Category<span class="token operator">:</span><span class="token operator">:</span>getName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>Collectors<span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        spu<span class="token punctuation">.</span><span class="token function">setCname</span><span class="token punctuation">(</span>StringUtils<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>names<span class="token punctuation">,</span><span class="token string">"/"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">//处理品牌信息</span>
        spu<span class="token punctuation">.</span><span class="token function">setBname</span><span class="token punctuation">(</span>brandService<span class="token punctuation">.</span><span class="token function">queryById</span><span class="token punctuation">(</span>spu<span class="token punctuation">.</span><span class="token function">getBrandId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

mapper

public interface SpuMapper extends Mapper<Spu> {
}
  • 1
  • 2
  • 3

Category中拓展查询名称的功能

页面需要商品的分类名称需要在这里查询,因此要额外提供查询分类名称的功能,

在CategoryService中添加功能:

    public List<Category> queryByIds(List<Long> ids){
        List<Category> categories = categoryMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(categories)){
            throw new LyException(ExceptionEnum.CATEGORY_NOT_FOND);
        }
        return categories;
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

mapper的selectByIDList方法是来自于通用mapper。不过需要我们在mapper上继承一个通用mapper接口:

public interface CategoryMapper extends Mapper<Category>, IdListMapper <Category,Long>{
}
  • 1
  • 2
  • 3

测试

1526280777975

                                </div><div data-report-view="{&quot;mod&quot;:&quot;1585297308_001&quot;,&quot;dest&quot;:&quot;https://blog.csdn.net/id5555/article/details/89327167&quot;,&quot;extend1&quot;:&quot;pc&quot;}"><div></div></div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet">
                                            <div class="more-toolbox">
            <div class="left-toolbox">
                <ul class="toolbox-list">
                    
                    <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#csdnc-thumbsup"></use>
                    </svg><span class="name">点赞</span>
                    <span class="count"></span>
                    </a></li>
                    <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-Collection-G"></use>
                    </svg><span class="name">收藏</span></a></li>
                    <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;1582594662_002&quot;}"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-fenxiang"></use>
                    </svg>分享</a></li>
                    <!--打赏开始-->
                                            <!--打赏结束-->
                                            <li class="tool-item tool-more">
                        <a>
                        <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                        </a>
                        <ul class="more-box">
                            <li class="item"><a class="article-report">文章举报</a></li>
                        </ul>
                    </li>
                                        </ul>
            </div>
                        </div>
        <div class="person-messagebox">
            <div class="left-message"><a href="https://blog.csdn.net/id5555">
                <img src="https://profile.csdnimg.cn/8/6/D/3_id5555" class="avatar_pic" username="id5555">
                                        <img src="https://g.csdnimg.cn/static/user-reg-year/1x/3.png" class="user-years">
                                </a></div>
            <div class="middle-message">
                                    <div class="title"><span class="tit"><a href="https://blog.csdn.net/id5555" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">smallmartial</a></span>
                                        </div>
                <div class="text"><span>发布了94 篇原创文章</span> · <span>获赞 8</span> · <span>访问量 1万+</span></div>
            </div>
                            <div class="right-message">
                                        <a href="https://im.csdn.net/im/main.html?userName=id5555" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                    </a>
                                                        <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                </div>
                        </div>
                </div>
</article>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值