-
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);
}
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.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);
其中page
和pageSize
应该是前端传进来的。既然有分页,所以要对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;
}
为了更通用化,创建一个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);
}
通用脱敏工具类:
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
:
========================================================================
搜索出来的结果要展示图片,价格,描述,销量,所以涉及到多表关联查询。
商品表关联商品规格表和商品图片表。
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;
创建搜索结果展示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中单引号要转义 "
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);
}
点击按钮查找是按照其三级分类的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);
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”)
public WJWJSONResult catItems(
@ApiParam(name = “catId”, value = “三级分类id”, required = true)
@RequestParam Integer catId,
@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 (catId == null){
return WJWJSONResult.errorMsg(null);
}
if (page == null){
page = 1;
}
if (pageSize == null){
pageSize = PAGE_SIZE;
}
PagedGridResult grid = itemService.searchItems(catId, sort, page, pageSize);
return WJWJSONResult.ok(grid);
}
=======================================================================
1. cookie
无需登录、无需查数据库、数据保存在浏览器端
优点: 性能好、访问快,没有和数据库交互
缺点:
-
换电脑购物车数据会丢失
-
电脑被其他人登录时可以看到cookie存的东西,隐私安全
2. Session
用户登录后,购物车数据放入用户会话
优点: 初期性能较好,访问快
缺点:
-
基于内存,用户量庞大影响服务器性能
-
只能存在于当前会话,不使用集群与分布式系统
3. 数据库
用户登录后,购物车数据存入数据库
优点: 数据持久化,可在任何地点、时间访问
缺点: 频繁读写数据库,造成数据库压力
4. Redis
用户登录后,购物车数据存入redis缓存
优点:
-
数据持久化,可在任何地点、时间访问
-
频繁读写只基于内存,不会造成数据库压力
-
适用于集群与分布式系统,可扩展性强
这里使用Cookie + Redis实现购物车。先将redis部分空缺。
点击【加入购物车】后调用addToCart方法:
先判断购物车里面商品数量不能太多:
创建购物车对象:
构建购物车里商品对象:需要有商品图片、名称、规格、原价、优惠价、数量
把商品添加到购物车,又会调用addItemToShopcart方法:
如果用户登陆要合并:
add方法传入一个user的id和shopcartItem业务对象,所以要先封装ShortcartBo类:
package com.wjw.pojo.bo;
/**
-
2 * @Author: 小王同学
-
3 * @Date: 2020/12/28 11:59
-
4
*/
public class ShopcartBO {
private String itemId;
private String itemImgUrl;
private String itemName;
private String specId;
private String specName;
private Integer buyCounts;
private String priceDiscount;
private String priceNormal;
…
}
创建ShopcartController
:
处理请求/shopcart/add
package com.wjw.controller;
import com.wjw.pojo.bo.ShopcartBO;
import com.wjw.utils.WJWJSONResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
-
2 * @Author: 小王同学
-
3 * @Date: 2020/12/20 16:29
-
4
*/
@RestController
@RequestMapping(“shopcart”)
@Api(value = “购物车接口controller”, tags = {“购物车接口相关的api”})
public class ShopcartController {
@ApiOperation(value = “添加商品到购物车”, notes = “添加商品到购物车”, httpMethod = “POST”)
@PostMapping(“/add”)
public WJWJSONResult add(@RequestParam String userId, @RequestBody ShopcartBO shopcartBO,
HttpServletRequest request, HttpServletResponse response) {
if (StringUtils.isBlank(userId)){
return WJWJSONResult.errorMsg(“”);
}
System.out.println(shopcartBO);
// TODO 前端用户在登录的情况下,添加商品到购物车,会同时在后端同步购物车到redis
return WJWJSONResult.ok();
}
}
在登录状态下测试:
前端向后台发送一个字符串,将商品的规格id以逗号为分隔进行拼接。
前端发送请求:
根据ShopcartBO
写sql语句:
SELECT
t_items.id as itemId,
t_items.item_name as itemName,
t_items_img.url as itemImgUrl,
t_times_spec.id as specId,
t_times_spec.name
as specName,
t_times_spec.price_discount as priceDiscount,
t_times_spec.price_normal as priceNormal
FROM
items_spec as t_times_spec
LEFT JOIN
items as t_items
ON
t_items.id = t_times_spec.item_id
LEFT JOIN
items_img as t_items_img
ON
t_items_img.item_id = t_items.id
WHERE
t_items_img.is_main = 1 # 拿主图
AND
t_times_spec.id IN (‘1’,‘3’,‘5’)
根据sql在ItemsMapperCustom.xml文件中添加语句:
SELECT
t_items.id as itemId,
t_items.item_name as itemName,
t_items_img.url as itemImgUrl,
t_times_spec.id as specId,
t_times_spec.name
as specName,
t_times_spec.price_discount as priceDiscount,
t_times_spec.price_normal as priceNormal
FROM
items_spec as t_times_spec
LEFT JOIN
items as t_items
ON
t_items.id = t_times_spec.item_id
LEFT JOIN
items_img as t_items_img
ON
t_items_img.item_id = t_items.id
WHERE
t_items_img.is_main = 1
AND
t_times_spec.id IN
#{specId}
这里用到的VO和上面定义的ShopcartBO基本类似,除了购买数量。定义ShopcartVO:
package com.wjw.pojo.vo;
/**
-
2 * @Author: 小王同学
-
3 * @Date: 2020/12/28 11:59
-
4
*/
public class ShopcartVO {
private String itemId;
private String itemImgUrl;
private String itemName;
private String specId;
private String specName;
private String priceDiscount;
private String priceNormal;
…
}
完善xml文件的命名空间ItemsMapperCustom
:
public List queryItemsBySpecIds(@Param(“paramsList”) List specIdsList);
service层,ItemService
中添加接口:
/**
-
根据拼接的规格ids查询最新的购物车中商品数据(用于刷新渲染购物车中商品数据)
-
@param specIds
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
总结
我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。
Mybatis源码解析
根据sql在ItemsMapperCustom.xml文件中添加语句:
SELECT
t_items.id as itemId,
t_items.item_name as itemName,
t_items_img.url as itemImgUrl,
t_times_spec.id as specId,
t_times_spec.name
as specName,
t_times_spec.price_discount as priceDiscount,
t_times_spec.price_normal as priceNormal
FROM
items_spec as t_times_spec
LEFT JOIN
items as t_items
ON
t_items.id = t_times_spec.item_id
LEFT JOIN
items_img as t_items_img
ON
t_items_img.item_id = t_items.id
WHERE
t_items_img.is_main = 1
AND
t_times_spec.id IN
#{specId}
这里用到的VO和上面定义的ShopcartBO基本类似,除了购买数量。定义ShopcartVO:
package com.wjw.pojo.vo;
/**
-
2 * @Author: 小王同学
-
3 * @Date: 2020/12/28 11:59
-
4
*/
public class ShopcartVO {
private String itemId;
private String itemImgUrl;
private String itemName;
private String specId;
private String specName;
private String priceDiscount;
private String priceNormal;
…
}
完善xml文件的命名空间ItemsMapperCustom
:
public List queryItemsBySpecIds(@Param(“paramsList”) List specIdsList);
service层,ItemService
中添加接口:
/**
-
根据拼接的规格ids查询最新的购物车中商品数据(用于刷新渲染购物车中商品数据)
-
@param specIds
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-YPGcElr7-1711168370410)]
[外链图片转存中…(img-YmZuckbk-1711168370411)]
[外链图片转存中…(img-8PaiyVaG-1711168370411)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-x2pwt6I3-1711168370412)]
总结
我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。实际上,作为程序员,丰富自己的知识储备,提升自己的知识深度和广度是很有必要的。
Mybatis源码解析
[外链图片转存中…(img-X9xIEPlR-1711168370412)]
[外链图片转存中…(img-YY7OdYvk-1711168370412)]