从0到1搭建精品电商项目(用于毕设、简历等)—— 项目完善首页

f.name as rootCatName,

f.slogan as slogan,

f.cat_image as catImage,

f.bg_color as bgColor,

i.id as itemId,

i.item_name as itemName,

ii.url as itemUrl,

i.created_time as createdTime

FROM

category f

LEFT JOIN

items i

ON

f.id = i.root_cat_id

LEFT JOIN

items_img ii

ON

i.id = ii.item_id

WHERE

f.type = 1 # 固定不变

AND

i.root_cat_id = 7 # 根据具体的类别确定

AND

ii.is_main = 1 # 判断是否是主图,固定不变

ORDER BY

i.created_time DESC

LIMIT 0,6; # 每个大类查6个,固定不变

在这里插入图片描述

2.2 商品推荐 - 实现接口与联调


CategoryService中添加查询六个商品的懒加载接口:

/**

  • 查询首页每个一级分类下的6条最新商品数据

  • @param rootCatId

  • @return

*/

public List getSixNewItemLazy(Integer rootCatId);

和之前获得子分类一样,修改mapper,在CategoryMapperCustom中追加接口:

public List getSixNewItemLazy(@Param(“paramsMap”) Map<String, Object> map);

这里用map传参。

基于上面的sql语句,CategoryMapperCustom.xml中追加:

SELECT

f.id as rootCatId,

f.name as rootCatName,

f.slogan as slogan,

f.cat_image as catImage,

f.bg_color as bgColor,

i.id as itemId,

i.item_name as itemName,

ii.url as itemUrl,

i.created_time as createdTime

FROM

category f

LEFT JOIN items i ON f.id = i.root_cat_id

LEFT JOIN items_img ii ON i.id = ii.item_id

WHERE

f.type = 1

AND

i.root_cat_id = #{paramsMap.rootCatId}

AND

ii.is_main = 1

ORDER BY

i.created_time DESC

LIMIT 0,6;

其中涉及到NewItemsVO

package com.wjw.pojo.vo;

import java.util.List;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/24 16:42

  • 4 最新商品推荐VO

*/

public class NewItemsVO {

private Integer rootCatId;

private String rootCatName;

private String slogan;

private String catImage;

private String bgColor;

private List simpleItemList;

}

simpleItemList中保存了SQL语句中查询出来的

在这里插入图片描述

SimpleItemVO的定义为:

package com.wjw.pojo.vo;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 15:57

  • 4 6个最新商品的简单数据类型

*/

public class SimpleItemVO {

private String itemId;

private String itemName;

private String itemUrl;

}

设置CategoryMapperCustomCategoryService的返回值类型:

在这里插入图片描述

在这里插入图片描述

由于mapper中定义了我们传进去的参数是一个Map,所以service实现类中要声明一个map

/**

  • 查询首页每个一级分类下的6条最新商品数据

  • @param rootCatId

  • @return

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public List getSixNewItemLazy(Integer rootCatId) {

HashMap<String, Object> map = new HashMap<>();

map.put(“rootCatId”, rootCatId);

return categoryMapperCustom.getSixNewItemLazy(map);

}

IndexController中添加相应的接口:

@ApiOperation(value = “查询每个一级分类下的最新6条商品数据”, notes = “查询每个一级分类下的最新6条商品数据”, httpMethod = “GET”)

@GetMapping(“/sixNewItems/{rootCatId}”)

public WJWJSONResult sixNewItems(

@ApiParam(name = “rootCatId”, value = “一级分类id”, required = true)

@PathVariable Integer rootCatId){

if (rootCatId == null) {

return WJWJSONResult.errorMsg(“分类不存在”);

}

List list = categoryService.getSixNewItemLazy(rootCatId);

return WJWJSONResult.ok(list);

}

启动测试可以发现随着鼠标慢慢往下划,页面慢慢的被加载出来。

2.3 搜索 - 商品详情功能分析


在这里插入图片描述

左边的图片是存放于items_img表中的:

在这里插入图片描述

详情中的信息存放于items表和items_spec表:

在这里插入图片描述

在这里插入图片描述

规格名称对应口味

在这里插入图片描述

宝贝详情存储在items_param表中

在这里插入图片描述

对于不同部分的加载,可以分开发送多个请求,用多个controller进行接收,将请求分散开来,速度稍微快一点。这里为了简便起见,还是用一次请求加载全部。

2.4 搜索 - 编写商品相关查询service


定义商品查询的接口:

package com.wjw.service;

import com.wjw.pojo.Items;

import com.wjw.pojo.ItemsImg;

import com.wjw.pojo.ItemsParam;

import com.wjw.pojo.ItemsSpec;

import java.util.List;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 16:47

  • 4

*/

public interface ItemService {

/**

  • 根据商品id查询详情

  • @param itemId

  • @return

*/

public Items queryItemById(String itemId);

/**

  • 根据商品id查询商品图片列表

  • @param itemId

  • @return

*/

public List queryItemImgList(String itemId);

/**

  • 根据商品id查询商品规格

  • @param itemId

  • @return

*/

public List queryItemSpecList(String itemId);

/**

  • 根据商品id查询商品参数

  • @param itemId

  • @return

*/

public ItemsParam queryItemParam(String itemId);

}

相应的具体实现(4个查询):

package com.wjw.service.impl;

import com.wjw.mapper.ItemsImgMapper;

import com.wjw.mapper.ItemsMapper;

import com.wjw.mapper.ItemsParamMapper;

import com.wjw.mapper.ItemsSpecMapper;

import com.wjw.pojo.Items;

import com.wjw.pojo.ItemsImg;

import com.wjw.pojo.ItemsParam;

import com.wjw.pojo.ItemsSpec;

import com.wjw.service.ItemService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 16:47

  • 4

*/

@Service

public class ItemServiceImpl implements ItemService {

@Autowired

private ItemsMapper itemsMapper;

@Autowired

private ItemsImgMapper itemsImgMapper;

@Autowired

private ItemsSpecMapper itemsSpecMapper;

@Autowired

private ItemsParamMapper itemsParamMapper;

/**

  • 根据商品id查询详情

  • @param itemId

  • @return

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public Items queryItemById(String itemId) {

return itemsMapper.selectByPrimaryKey(itemId);

}

/**

  • 根据商品id查询商品图片列表

  • @param itemId

  • @return

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public List queryItemImgList(String itemId) {

Example itemsImgExp = new Example(ItemsImg.class);

Example.Criteria criteria = itemsImgExp.createCriteria();

criteria.andEqualTo(“itemId”, itemId);

return itemsImgMapper.selectByExample(itemsImgExp);

}

/**

  • 根据商品id查询商品规格

  • @param itemId

  • @return

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public List queryItemSpecList(String itemId) {

Example itemsSpecExp = new Example(ItemsSpec.class);

Example.Criteria criteria = itemsSpecExp.createCriteria();

criteria.andEqualTo(“itemId”, itemId);

return itemsSpecMapper.selectByExample(itemsSpecExp);

}

/**

  • 根据商品id查询商品参数

  • @param itemId

  • @return

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public ItemsParam queryItemParam(String itemId) {

Example itemsParamExp = new Example(ItemsParam.class);

Example.Criteria criteria = itemsParamExp.createCriteria();

criteria.andEqualTo(“itemId”, itemId);

return itemsParamMapper.selectOneByExample(itemsParamExp);

}

}

2.5 搜索 - 联调详情页与排查bug


前端请求url:

在这里插入图片描述

创建ItemsController:

由于这里一下查了四组参数要同时返回,所以还要借助VO

package com.wjw.pojo.vo;

import com.wjw.pojo.Items;

import com.wjw.pojo.ItemsImg;

import com.wjw.pojo.ItemsParam;

import com.wjw.pojo.ItemsSpec;

import java.util.List;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 18:49

  • 4 商品详情VO

*/

public class ItemInfoVO {

private Items item;

private List itemImgList;

private List itemSpecList ;

private ItemsParam itemParams;

}

controller:

package com.wjw.controller;

import com.wjw.pojo.Items;

import com.wjw.pojo.ItemsImg;

import com.wjw.pojo.ItemsParam;

import com.wjw.pojo.ItemsSpec;

import com.wjw.pojo.vo.ItemInfoVO;

import com.wjw.service.ItemService;

import com.wjw.utils.WJWJSONResult;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiOperation;

import io.swagger.annotations.ApiParam;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 17:15

  • 4

*/

@Api(value = “商品接口”, tags = {“商品信息展示的相关接口”})

@RestController

@RequestMapping(“items”)

public class ItemsController {

@Autowired

private ItemService itemService;

@ApiOperation(value = “查询商品详情”, notes = “查询商品详情”, httpMethod = “GET”)

@GetMapping(“/info/{itemId}”)

public WJWJSONResult info(

@ApiParam(name = “itemId”, value = “商品id”, required = true)

@PathVariable String itemId){

if (StringUtils.isBlank(itemId)){

return WJWJSONResult.errorMsg(null);

}

Items item = itemService.queryItemById(itemId);

List itemImgList = itemService.queryItemImgList(itemId);

List itemSpecList = itemService.queryItemSpecList(itemId);

ItemsParam itemParams = itemService.queryItemParam(itemId);

ItemInfoVO itemInfoVO = new ItemInfoVO();

itemInfoVO.setItem(item);

itemInfoVO.setItemImgList(itemImgList);

itemInfoVO.setItemSpecList(itemSpecList);

itemInfoVO.setItemParams(itemParams);

return WJWJSONResult.ok(itemInfoVO);

}

}

在这里插入图片描述

要注意VO的字段名一定要和前端定义的一样:

在这里插入图片描述

在这里插入图片描述

3 商品评价功能开发

========================================================================

3.1 数据库设计


订单完成之后,在用户中心可以进行评价操作,展示评论时还要把用户信息进行一个隐私处理。还要涉及分页、分类操作。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

表的设计要和用户表商品表关联,商品有不同规格所以要有规格id、名称

评价等级:1:好评 2:中评 3:差评

3.2 实现评价等级数量查询


在ItemService中添加和评价有关的查询:

/**

  • 根据商品id查询商品的评价等级数量

  • @param itemId

*/

public CommentLevelCountsVO queryCommentCounts(String itemId);

将商品评价的展示封装成为VO:

package com.wjw.pojo.vo;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/25 20:33

  • 4 用于展示商品评价数量的VO

*/

public class CommentLevelCountsVO {

/**

  • 总评价数

*/

public Integer totalCounts;

/**

  • 好评

*/

public Integer goodCounts;

/**

  • 中评

*/

public Integer normalCounts;

/**

  • 差评

*/

public Integer badCounts;

}

创建评价等级的枚举:

package com.wjw.enums;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/21 21:04

  • 4 商品评价等级枚举

*/

public enum CommentLevel {

GOOD(1, “好评”),

NORMAL(2, “中评”),

BAD(3, “差评”);

public final Integer type;

public final String value;

CommentLevel(Integer type, String value) {

this.type = type;

this.value = value;

}

}

service的具体实现:

@Autowired

private ItemsCommentsMapper itemsCommentsMapper;

/**

  • 根据商品id查询商品的评价等级数量

  • @param itemId

*/

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public CommentLevelCountsVO queryCommentCounts(String itemId) {

Integer goodCounts = getCommentCounts(itemId, CommentLevel.GOOD.type);

Integer normalCounts = getCommentCounts(itemId, CommentLevel.NORMAL.type);

Integer badCounts = getCommentCounts(itemId, CommentLevel.BAD.type);

Integer totalCounts = goodCounts + normalCounts + badCounts;

CommentLevelCountsVO countsVO = new CommentLevelCountsVO();

countsVO.setTotalCounts(totalCounts);

countsVO.setGoodCounts(goodCounts);

countsVO.setNormalCounts(normalCounts);

countsVO.setBadCounts(badCounts);

return countsVO;

}

/**

  • 查询某个评价等级的通用方法

  • @param itemId

  • @param level

  • @return

*/

Integer getCommentCounts(String itemId, Integer level) {

ItemsComments condition = new ItemsComments();

condition.setItemId(itemId);

if (level != null){

condition.setCommentLevel(level);

}

return itemsCommentsMapper.selectCount(condition);

}

在IndexController中添加查询评价等级数量的接口:

在这里插入图片描述

注意这里路径用的是?这种形式,不是前面的/这种形式,所以对应的参数的注解为@RequestParam

@ApiOperation(value = “查询商品评价等级”, notes = “查询商品评价等级”, httpMethod = “GET”)

@GetMapping(“/commentLevel”)

public WJWJSONResult commentLevel(

@ApiParam(name = “itemId”, value = “商品id”, required = true)

@RequestParam String itemId){

if (StringUtils.isBlank(itemId)){

return WJWJSONResult.errorMsg(null);

}

CommentLevelCountsVO countsVO = itemService.queryCommentCounts(itemId);

return WJWJSONResult.ok(countsVO);

}

在这里插入图片描述

在这里插入图片描述

3.3 编写自定义mapper查询


SELECT

ic.comment_level as commentLevel,

ic.content as content,

ic.sepc_name as specName,

ic.created_time as createdTime,

u.face as userFace,

u.nickname as nickname

FROM

items_comments as ic

LEFT JOIN

users as u

ON

ic.user_id = u.id

WHERE

ic.item_id = ‘cake-1001’ # 指定查哪个商品评价

AND

ic.comment_level = 1; # 查好评

创建自定义ItemsMapperCustom.xml:

<?xml version="1.0" encoding="UTF-8" ?>

SELECT

ic.comment_level as commentLevel,

ic.content as content,

ic.sepc_name as specName,

ic.created_time as createdTime,

u.face as userFace,

u.nickname as nickname

FROM

items_comments as ic

LEFT JOIN

users as u

ON

ic.user_id = u.id

WHERE

ic.item_id =

AND

ic.comment_level = 1

自定义mapper接口:

package com.wjw.mapper;

public interface ItemsMapperCustom {

}

上面两个文件未编写完毕,下面继续。

Sql语句的输出要返回给前端进行展示,所以要定义一个VO:

package com.wjw.pojo.vo;

import java.util.Date;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/26 10:31

  • 4 用于展示商品评价的VO

*/

public class ItemCommentVO {

private Integer commentLevel;

private String content;

private String specName;

private Date createdTime;

private String userFace;

private String nickname;

}

在xml文件的namespace中添加相应的方法:

package com.wjw.mapper;

import com.wjw.pojo.vo.ItemCommentVO;

import org.apache.ibatis.annotations.Param;

import java.util.List;

import java.util.Map;

public interface ItemsMapperCustom {

public List queryItemComments(@Param(“paramsMap”) Map<String, Object> map);

}

将上面的VO作为resultType补全xml文件:

在这里插入图片描述

3.4 编写service


3.4.1 基础实现

ItemService中添加接口:

/**

  • 根据商品id和评价等级查询评价(分页)

  • @param itemId

  • @param level

  • @return

*/

public List queryPagedComments(String itemId, Integer level);

具体实现:

@Autowired

private ItemsMapperCustom itemsMapperCustom;

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public List queryPagedComments(String itemId, Integer level) {

// 请求参数

HashMap<String, Object> map = new HashMap<>();

map.put(“itemId”, itemId);

map.put(“level”, level);

List list = itemsMapperCustom.queryItemComments(map);

return list;

}

3.4.2 添加分页功能

1. 父工程引入分页插件依赖

com.github.pagehelper

pagehelper-spring-boot-starter

1.2.12

2. foodie-dev-api配置yml

分页插件配置

pagehelper:

helperDialect: mysql

supportMethodsArguments: true

3. 使用分页插件,在查询前使用分页插件,原理:统一拦截sql,为其提供分页功能

/**

  • page: 第几页

  • pageSize: 每页显示条数

*/

PageHelper.startPage(page, pageSize);

其中pagepageSize应该是前端传进来的。既然有分页,所以要对queryPagedComments再添加两个参数。

在这里插入图片描述

4.分页数据封装到PagedGridResult.java 传给前端

PageInfo<?> pageList = new PageInfo<>(list);

PagedGridResult grid = new PagedGridResult();

grid.setPage(page);

grid.setRows(list);

grid.setTotal(pageList.getPages());

grid.setRecords(pageList.getTotal());

其中PagedGridResult是自己封装的类。

package com.wjw.utils;

import java.util.List;

/**

  • @Title: PagedGridResult.java

  • @Package com.wjw.utils

  • @Description: 用来返回分页Grid的数据格式

  • Copyright: Copyright © 2019

*/

public class PagedGridResult {

private int page; // 当前页数

private int total; // 总页数

private long records; // 总记录数

private List<?> rows; // 每行显示的内容

}

同时service方法的返回值也要改变。

在这里插入图片描述

完整的queryPagedComments实现:

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public PagedGridResult queryPagedComments(String itemId, Integer level,

Integer page, Integer pageSize) {

// 请求参数

HashMap<String, Object> map = new HashMap<>();

map.put(“itemId”, itemId);

map.put(“level”, level);

/**

  • page: 第几页

  • pageSize: 每页显示条数

*/

PageHelper.startPage(page, pageSize);

List list = itemsMapperCustom.queryItemComments(map);

return setterPagedGrid(list, page);

}

/**

  • 抽取设置分页对象的方法

  • @param list

  • @param page

  • @return

*/

private PagedGridResult setterPagedGrid(List<?> list, Integer page){

PageInfo<?> pageList = new PageInfo<>(list);

PagedGridResult grid = new PagedGridResult();

grid.setPage(page);

grid.setRows(list);

grid.setTotal(pageList.getPages());

grid.setRecords(pageList.getTotal());

return grid;

}

3.5 商品评价Controller


在这里插入图片描述

为了更通用化,创建一个BaseController:

package com.wjw.controller;

import org.springframework.stereotype.Controller;

import org.springframework.transaction.annotation.Transactional;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/20 16:29

  • 4

*/

@Controller

public class BaseController {

public static final Integer COMMENT_PAGE_SIZE = 10;

}

ItemsController中添加方法:

先继承BaseController

在这里插入图片描述

@ApiOperation(value = “查询商品评价”, notes = “查询商品评价”, httpMethod = “GET”)

@GetMapping(“/comments”)

public WJWJSONResult comments(

@ApiParam(name = “itemId”, value = “商品id”, required = true)

@RequestParam String itemId,

@ApiParam(name = “level”, value = “评价等级”, required = false)

@RequestParam Integer level,

@ApiParam(name = “page”, value = “查询下一页的第几页”, required = false)

@RequestParam Integer page,

@ApiParam(name = “pageSize”, value = “每一页显示的记录数”, required = false)

@RequestParam Integer pageSize){

if (StringUtils.isBlank(itemId)){

return WJWJSONResult.errorMsg(null);

}

if (page == null){

page = 1;

}

if (pageSize == null){

pageSize = COMMENT_PAGE_SIZE;

}

PagedGridResult grid = itemService.queryPagedComments(itemId, level, page, pageSize);

return WJWJSONResult.ok(grid);

}

3.6 信息脱敏


通用脱敏工具类:

package com.wjw.utils;

import sun.applet.Main;

/**

  • 通用脱敏工具类

  • 可用于:

  •  用户名
    
  •  手机号
    
  •  邮箱
    
  •  地址等
    

*/

public class DesensitizationUtil {

private static final int SIZE = 6;

private static final String SYMBOL = “*”;

public static void main(String[] args) {

String name = commonDisplay(“N小王日记”);

String mobile = commonDisplay(“13900000000”);

String mail = commonDisplay(“admin@xw.com”);

String address = commonDisplay(“南京北京东路888号”);

System.out.println(name);

System.out.println(mobile);

System.out.println(mail);

System.out.println(address);

}

/**

  • 通用脱敏方法

  • @param value

  • @return

*/

public static String commonDisplay(String value) {

if (null == value || “”.equals(value)) {

return value;

}

int len = value.length();

int pamaone = len / 2;

int pamatwo = pamaone - 1;

int pamathree = len % 2;

StringBuilder stringBuilder = new StringBuilder();

if (len <= 2) {

if (pamathree == 1) {

return SYMBOL;

}

stringBuilder.append(SYMBOL);

stringBuilder.append(value.charAt(len - 1));

} else {

if (pamatwo <= 0) {

stringBuilder.append(value.substring(0, 1));

stringBuilder.append(SYMBOL);

stringBuilder.append(value.substring(len - 1, len));

} else if (pamatwo >= SIZE / 2 && SIZE + 1 != len) {

int pamafive = (len - SIZE) / 2;

stringBuilder.append(value.substring(0, pamafive));

for (int i = 0; i < SIZE; i++) {

stringBuilder.append(SYMBOL);

}

if ((pamathree == 0 && SIZE / 2 == 0) || (pamathree != 0 && SIZE % 2 != 0)) {

stringBuilder.append(value.substring(len - pamafive, len));

} else {

stringBuilder.append(value.substring(len - (pamafive + 1), len));

}

} else {

int pamafour = len - 2;

stringBuilder.append(value.substring(0, 1));

for (int i = 0; i < pamafour; i++) {

stringBuilder.append(SYMBOL);

}

stringBuilder.append(value.substring(len - 1, len));

}

}

return stringBuilder.toString();

}

}

在这里插入图片描述

修改service层queryPagedComments

在这里插入图片描述

在这里插入图片描述

4 商品搜索功能开发

========================================================================

4.1 sql编写


在这里插入图片描述

搜索出来的结果要展示图片,价格,描述,销量,所以涉及到多表关联查询。

商品表关联商品规格表和商品图片表。

在这里插入图片描述

SELECT

i.id as itemId,

i.item_name as itemName,

i.sell_counts as sellConuts,

ii.url as imgUrl,

tempSpec.price_discount as price

FROM

items as i

LEFT JOIN

items_img ii

ON

i.id = ii.item_id

LEFT JOIN

(

SELECT

item_id, MIN(price_discount) as price_discount

FROM

items_spec

GROUP BY

item_id

) as tempSpec

ON

i.id = tempSpec.item_id

WHERE

ii.is_main = 1;

4.2 实现搜索功能


创建搜索结果展示VO:

后端涉及到的金额是以“分”为单位的int型数据,前端负责做除以100的展示

package com.wjw.pojo.vo;

/**

  • 2 * @Author: 小王同学

  • 3 * @Date: 2020/12/26 14:33

  • 4 用于展示商品搜索列表的VO

*/

public class SearchItemsVO {

private String itemId;

private String itemName;

private int sellCounts;

private String imgUrl;

private int price;

}

实现mapper,在ItemsMapperCustom.xml中添加查询语句:

  • 拼接字符串要用$符,而不是#占位符

  • 规定默认排序(根据name)传入的参数为 paramsMap.sort = k;

  • 销量排序 paramsMap.sort = c;

  • 价格排序 paramsMap.sort = p;

mybatis中单引号要转义 &quot;

SELECT

i.id as itemId,

i.item_name as itemName,

i.sell_counts as sellCounts,

ii.url as imgUrl,

tempSpec.price_discount as price

FROM

items as i

LEFT JOIN

items_img ii

ON

i.id = ii.item_id

LEFT JOIN

( SELECT item_id, MIN(price_discount) as price_discount FROM items_spec GROUP BY item_id ) as tempSpec

ON

i.id = tempSpec.item_id

WHERE

ii.is_main = 1

AND i.item_name like ‘%${paramsMap.keywords}%’

order by

i.sell_counts desc

tempSpec.price_discount asc

i.item_name asc

在mapper的命名空间ItemsMapperCustom中添加searchItems方法:

public List searchItems(@Param(“paramsMap”) Map<String, Object> map);

编写service层,ItemService中添加:

/**

  • 搜索商品列表

  • @param keyword

  • @param sort 排序类型:k,c,p

  • @param page

  • @param pageSize

  • @return

*/

public PagedGridResult searchItems(String keyword, String sort, Integer page, Integer pageSize);

service层对应实现类:

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public PagedGridResult searchItems(String keywords, String sort, Integer page, Integer pageSize) {

// 请求参数

HashMap<String, Object> map = new HashMap<>();

map.put(“keywords”, keywords);

map.put(“sort”, sort);

PageHelper.startPage(page, pageSize);

List list = itemsMapperCustom.searchItems(map);

return setterPagedGrid(list, page);

}

ItemsController中添加相应的接口:

前端请求地址:

在这里插入图片描述

@ApiOperation(value = “搜索商品列表”, notes = “搜索商品列表”, httpMethod = “GET”)

@GetMapping(“/search”)

public WJWJSONResult search(

@ApiParam(name = “keywords”, value = “关键字”, required = true)

@RequestParam String keywords,

@ApiParam(name = “sort”, value = “排序”, required = false)

@RequestParam String sort,

@ApiParam(name = “page”, value = “查询下一页的第几页”, required = false)

@RequestParam Integer page,

@ApiParam(name = “pageSize”, value = “每一页显示的记录数”, required = false)

@RequestParam Integer pageSize){

if (StringUtils.isBlank(keywords)){

return WJWJSONResult.errorMsg(null);

}

if (page == null){

page = 1;

}

if (pageSize == null){

pageSize = PAGE_SIZE;

}

PagedGridResult grid = itemService.searchItems(keywords, sort, page, pageSize);

return WJWJSONResult.ok(grid);

}

在这里插入图片描述

4.3 前端业务与分类搜索查询


在这里插入图片描述

点击按钮查找是按照其三级分类的id来查找该分类下的所有商品。所以前端就有两种方式跳转到搜索的结果页面。

  • 一种是输入关键字搜索:

在这里插入图片描述

  • 另一种是点击了三级分类标签后的搜索:

在这里插入图片描述

  • 搜索界面进行展示时也会判断是属于哪一类的搜索:

在这里插入图片描述

在ItemsMapperCustom.xml中添加根据三级标签搜索的功能:

类似上面的根据关键词的搜索

SELECT

i.id as itemId,

i.item_name as itemName,

i.sell_counts as sellCounts,

ii.url as imgUrl,

tempSpec.price_discount as price

FROM

items as i

LEFT JOIN

items_img ii

ON

i.id = ii.item_id

LEFT JOIN

( SELECT item_id, MIN(price_discount) as price_discount FROM items_spec GROUP BY item_id ) as tempSpec

ON

i.id = tempSpec.item_id

WHERE

ii.is_main = 1

AND

i.cat_id = #{paramsMap.catId}

order by

i.sell_counts desc

tempSpec.price_discount asc

i.item_name asc

在xml文件的namespace中定义searchItemsByThirdCat方法:

public List searchItemsByThirdCat(@Param(“paramsMap”) Map<String, Object> map);

4.4 实现分类搜索商品查询


service层实现,在ItemService中追加接口:

/**

  • 根据三级分类id搜索商品列表

  • @param catId

  • @param sort 排序类型:k,c,p

  • @param page

  • @param pageSize

  • @return

*/

public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize);

对应的service层具体实现:

类似上面的根据关键词的搜索

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize) {

// 请求参数

HashMap<String, Object> map = new HashMap<>();

map.put(“catId”, catId);

map.put(“sort”, sort);

PageHelper.startPage(page, pageSize);

List list = itemsMapperCustom.searchItemsByThirdCat(map);

return setterPagedGrid(list, page);

}

ItemsController中追加相应的接口:

@ApiOperation(value = “通过分类id搜索商品列表”, notes = “通过分类id搜索商品列表”, httpMethod = “GET”)

@GetMapping(“/catItems”)

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

image

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

image

互联网Java程序员面试必备问题解析及文档学习笔记

image

Java架构进阶视频解析合集

索:

在这里插入图片描述

在ItemsMapperCustom.xml中添加根据三级标签搜索的功能:

类似上面的根据关键词的搜索

SELECT

i.id as itemId,

i.item_name as itemName,

i.sell_counts as sellCounts,

ii.url as imgUrl,

tempSpec.price_discount as price

FROM

items as i

LEFT JOIN

items_img ii

ON

i.id = ii.item_id

LEFT JOIN

( SELECT item_id, MIN(price_discount) as price_discount FROM items_spec GROUP BY item_id ) as tempSpec

ON

i.id = tempSpec.item_id

WHERE

ii.is_main = 1

AND

i.cat_id = #{paramsMap.catId}

order by

i.sell_counts desc

tempSpec.price_discount asc

i.item_name asc

在xml文件的namespace中定义searchItemsByThirdCat方法:

public List searchItemsByThirdCat(@Param(“paramsMap”) Map<String, Object> map);

4.4 实现分类搜索商品查询


service层实现,在ItemService中追加接口:

/**

  • 根据三级分类id搜索商品列表

  • @param catId

  • @param sort 排序类型:k,c,p

  • @param page

  • @param pageSize

  • @return

*/

public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize);

对应的service层具体实现:

类似上面的根据关键词的搜索

@Transactional(propagation = Propagation.SUPPORTS)

@Override

public PagedGridResult searchItems(Integer catId, String sort, Integer page, Integer pageSize) {

// 请求参数

HashMap<String, Object> map = new HashMap<>();

map.put(“catId”, catId);

map.put(“sort”, sort);

PageHelper.startPage(page, pageSize);

List list = itemsMapperCustom.searchItemsByThirdCat(map);

return setterPagedGrid(list, page);

}

ItemsController中追加相应的接口:

@ApiOperation(value = “通过分类id搜索商品列表”, notes = “通过分类id搜索商品列表”, httpMethod = “GET”)

@GetMapping(“/catItems”)

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

[外链图片转存中…(img-gm2PCfjt-1714566304904)]

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

[外链图片转存中…(img-dH9rxkR6-1714566304904)]

互联网Java程序员面试必备问题解析及文档学习笔记

[外链图片转存中…(img-BNlKrxRq-1714566304904)]

Java架构进阶视频解析合集

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值