【基于SprintBoot+Mybatis+Mysql】电脑商城项目之加入购物车和显示购物车列表

🧸安清h:个人主页
🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】
🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。

目录
🚀1.加入购物车-数据创建
🚀2.加入购物车-实体类
🚀3.加入购物车-持久层
✨3.1规划需要执行的SQL语句
✨3.2设计接口和抽象方法
✨3.3 SQL映射
🚀4.加入购物车-业务层
✨4.1规划异常
✨4.2接口和抽象方法的设计
✨4.3实现接口
🚀5.加入购物车-控制层
✨5.2设计请求
✨5.3处理请求
🚀6.加入购物车-前端页面
🎯1.显示购物车列表- 持久层
✨1.1规划SQL语句
✨1.2构建VO类
✨1.3设计接口和抽象方法
✨1.4配置SQL映射
🎯2.显示购物车列表- 业务层
🎯3.显示购物车列表- 控制层
✨3.1设计请求
✨3.2处理请求
🎯4.显示购物车列表- 前端页面
🎃1. 增加购物车商品数量-持久层
✨1.1规划需要执行的SQL语句
✨1.2设计接口和抽象方法
✨1.3配置SQL映射
🎃 2.增加购物车商品数量-业务层
✨2.1规划异常
✨2.2设计接口和抽象方法
✨ 2.3实现方法
🎃 3.增加购物车商品数量-控制层
✨3.1处理异常
✨3.2设计请求
✨3.3处理请求
🎃 4.增加购物车商品数量-前端页面
🚀1.加入购物车-数据创建
CREATE TABLE t_cart (cid INT AUTO_INCREMENT COMMENT '购物车数据id',uid INT NOT NULL COMMENT '用户id',pid INT NOT NULL COMMENT '商品id',price BIGINT COMMENT '加入时商品单价',num INT COMMENT '商品数量',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (cid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
num:当用户重复添加商品时,只修改num就可以了,无需再重复添加商品。
🚀2.加入购物车-实体类
public class Cart extends BaseEntity{private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;
。。。。。。
}
🚀3.加入购物车-持久层
✨3.1规划需要执行的SQL语句
1.向购物车表中插入数据。
insert into t_cart values(值列表)
2.当当前的商品已经在购物车中存在,则直接更新num的数量即可。
update t_cart set num=? where cid=?
3.在插入或更新具体执行那个语句,取决于数据库中是否有当前的这个购物车商品的数据,得去查询才能查询。对当前的用户的pid进行查询,加上uid=?,而不是对当前的整张表进行查询。
select * from t_cart where pid=? and uid=?
✨3.2设计接口和抽象方法
创建一个CartMapper接口持久层的文件。
/*** 插入购物车数据* @param cart 购物车数据* @return 受影响的行数* 插入时最好放在一个对象中传递,所以用Cart参数列表* 插入后在业务层可能调用,需要有返回值判断能否插入成功*/Integer insert(Cart cart);/*** 更新购物车某件商品的数量* @param cid 购物数据id* @param num 更新的数量* @param modifiedUser 修改人* @param modifiedTime 修改时间* @return 受影响的行数* 更新时涉及到修改人和修改时间,除了cid外,还需要知道数量num*/Integer updateNumByCid(Integer cid, Integer num, String modifiedUser, Date modifiedTime);/*** 根据用户的id和商品的id来查询购物车中的数据* @param uid 用户id* @param pid 商品id*/Cart findByUidAndPid(Integer uid,Integer pid);
✨3.3 SQL映射
1.创建一个CartMapper.xml映射文件,添加以上三个抽象方法的SQL映射。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.CartMapper"><resultMap id="CartEntityMap" type="com.cy.store.entity.Cart"><id property="cid" column="cid"/><result column="created_user" property="createdUser"></result><result column="created_time" property="createdTime"></result><result column="modified_user" property="modifiedUser"></result><result column="modified_time" property="modifiedTime"></result></resultMap><insert id="insert" useGeneratedKeys="true" keyProperty="cid">insert into t_cart (uid, pid, price, num, created_user, created_time, modified_user, modified_time)values (#{uid}, #{pid}, #{price}, #{num}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})</insert><update id="updateNumByCid">update t_cart set num=#{num},modified_user=#{modifiedUser},modified_time=#{modifiedTime}where cid=#{cid}</update><select id="findByUidAndPid" resultMap="CartEntityMap">select * from t_cart where pid=#{pid} and uid=#{uid}</select>
</mapper>
2.进行测试
@SpringBootTest
public class CartMapperTests {@Autowiredprivate CartMapper cartMapper;@Testpublic void insert(){Cart cart = new Cart();cart.setNum(3);cart.setPid(10000002);cart.setUid(6);cartMapper.insert(cart);}@Testpublic void updateNumByCid(){cartMapper.updateNumByCid(1,6,"小明",new Date());}@Testpublic void findByUidAndPid(){Cart cart = cartMapper.findByUidAndPid(6,10000002);System.err.println(cart);}
}
🚀4.加入购物车-业务层
✨4.1规划异常
1.插入数据时可能产生异常:InsertException。
2.更新数据时可能产生异常:UpdateException。
✨4.2接口和抽象方法的设计
分析:
1.首先要进行商品的查询,这里面通过findByUidAndPid方法必须要传递过来的是uid和pid的字段。
2.假设拿到后,就要对原有的数据进行更新,需要传递的字段有:cid,num,username。
/*** 将商品添加到购物车中* @param uid 用户id* @param pid 商品id* @param amount 新增数量* @param username 用户名(修改者)*/void addToCart(Integer uid,Integer pid,Integer amount,String username);
✨4.3实现接口
1.创建一个CartServiceImpl的实现类。
@Service
public class CartServiceImpl implements ICartService {
//购物车的业务层依赖于购物车的持久层和商品的持久层@Autowiredprivate CartMapper cartMapper;@Autowired//购物车中的一些定义的字段实际上是从商品表中分离出来的private ProductMapper productMapper;@Overridepublic void addToCart(Integer uid, Integer pid, Integer amount, String username) {//查询当前要添加的购物车是否在表中已存在Cart result = cartMapper.findByUidAndPid(uid,pid);Date date = new Date();if(result == null){ //表示这个商品从来没有被添加到购物车中,则进行新增操作//创建一个Cart对象Cart cart = new Cart();//补全数据:首先补全参数传递过来的数据cart.setPid(pid);cart.setUid(uid);//这里的amount暂且理解为在前端加好,把总数传递过来cart.setNum(amount);//补全价格:来自于商品中的数据Product product = productMapper.findById(pid);cart.setPrice(product.getPrice());//补全四日志cart.setCreatedUser(username);cart.setCreatedTime(date);cart.setModifiedUser(username);cart.setModifiedTime(date);//执行数据的插入操作Integer rows = cartMapper.insert(cart);if(rows != 1){throw new InsertException("插入数据时产生未知的异常");}}else{ //表示当前商品已经存在于购物车中,则更新这条数据的num值Integer num = result.getNum()+amount;Integer cid = result.getCid();Integer rows = cartMapper.updateNumByCid(cid,num,username,date);if(rows != 1){throw new UpdateException("更新时产生未知的异常");}}}
}
2. 再创建对应的测试类CartServiceTests。
@SpringBootTest
public class CartServiceTests {@Autowiredprivate ICartService cartService;@Testpublic void addToCart(){cartService.addToCart(6,10000013,2,"北伐不成功不改名");}
}
🚀5.加入购物车-控制层
1.没有需要处理的异常。
✨5.2设计请求
请求路径:/carts/add_to_cart
请求方式:POST
请求数据:Integer pid,Integer amount,HttpSession session
响应结果:JsonResult<Void>
✨5.3处理请求
1.创建一个CartController类,具体代码如下:
@RequestMapping("carts")
@RestController
public class CartController extends BaseController{@Autowiredprivate ICartService cartService;@RequestMapping("add_to_cart")public JsonResult<Void> addToCart(Integer pid, Integer amount, HttpSession session){cartService.addToCart(getuidFromSession(session),pid,amount,getUsernameFromSession(session));return new JsonResult<>(OK);}
}
2.登录后访问:http://localhost:8080/carts/add_to_cart?pid=10000003&amount=1
🚀6.加入购物车-前端页面
在product.html页面给【加入购物车】按钮添加点击事件,并发送ajax请求。
$("#btn-add-to-cart").click(function (){$.ajax({url:"/carts/add_to_cart",type:"POST",data:{"pid":id,"amount":$("#num").val()},dataType:"JSON",success:function (json){if(json.state==200){alert("加入购物车成功");}else{alert("加入购物车失败");}},error:function (xhr){alert("加入购物车时产生未知的异常"+xhr.message);}});});
在ajax函数中data参数的数据设置的方式:
- data:$("form表单选择").serialize()。适合要么就是可以全部选择的,或者手动输入的串的类型。当参数过多并且在同一个字符串中。
- data:new FormData($("form表单选择")[0])。只适用提交文件,其他形式提交不了。
- data:"username=Tom"。适合参数值固定并且参数值列表有限,可以进行手动拼接。
let user = "tom"; data:"username="+user - 适用JSON格式提交数据:
data:{"username":"tom","age":18,"sex":0 }
🎯1.显示购物车列表- 持久层
✨1.1规划SQL语句

分析上图可知,红线框住的图片和商品标题来自于product表,而蓝线框住的应该属于 cart表,单价和数量应该是从购物车中传过来的,再根据两者计算总金额。由于数据来自于两张表中的部分字段,所以要用到关联查询。
#多表查询如果字段不重复则不需要显式声明字段属于哪张表
select cid,uid,pid,t_cart.price,t_cart.num,t_product.image,t_product.title,t_product.price as real
from t_cart left join t_product on t_cart.pid=t_product.id
where uid=#{uid}
order by t_cart.createdTime DESC;
✨1.2构建VO类
VO:Value Object,值对象。当进行select查询时,查询的结果属于多张表中的内容,此时发现结果集不能直接使用某个POJO实体类来接收,POJO实体类不能包含多表查询出来的结果。解决方案:重新构建一个新的对象,这个对象用于存储所查询出来的结果集对应的映射,所以把这样的对象称之为值对象。
在com.cy.store下新建一个包VO,在VO包里创建CartVO类。
//购物车数据的VO类(Value Object)值对象
public class CartVO implements Serializable {private Integer cid;private Integer uid;private Integer pid;private Long price;private Integer num;private String title;private String image;private Long realPrice;
......
}
✨1.3设计接口和抽象方法
在CartMapper中编写如下代码:
List<CartVO> findVOByUid(Integer uid);
✨1.4配置SQL映射
<select id="findVOByUid" resultType="com.cy.store.Vo.CartVO">select cid,uid,pid,t_cart.price,t_cart.num,t_product.image,t_product.title,t_product.price as realPricefrom t_cart left join t_product on t_cart.pid=t_product.idwhere uid=#{uid}order by t_cart.createdTime DESC</select>
单元测试
@Testpublic void findVOByUid(){System.out.println(cartMapper.findVOByUid(6));}
🎯2.显示购物车列表- 业务层
1.先编写业务层的接口方法。
List<CartVO> getVOByUid(Integer uid);
2.在实现类中实现方法。
@Overridepublic List<CartVO> getVOByUid(Integer uid) {List<CartVO> list = cartMapper.findVOByUid(uid);return list;}
🎯3.显示购物车列表- 控制层
✨3.1设计请求
请求路径:/carts/(只要发一个carts就可以把列表返回,不需要carts下的什么)
请求方式:GET
请求数据:HttpSession session
响应结果:JsonResult<List<CartVO>>
✨3.2处理请求
1.实现请求处理方法的代码编写。
@RequestMapping({"/",""})public JsonResult<List<CartVO>> getVOByUid(HttpSession session){List<CartVO> data = cartService.getVOByUid(getuidFromSession(session));return new JsonResult<>(OK,data);}
2.先登录再进行功能测试,访问http://localhost:8080/carts。
🎯4.显示购物车列表- 前端页面
要把cart.html页面通过向Controller层中的getVOByUid方法发送请求就可以返回所有的数据。
1.先注释掉以下代码:
<script src="../js/cart.js" type="text/javascript" charset="utf-8"></script>
2.用户一打开页面就自动发送请求,请求数据。读取form表单,对它的结构做一个了解,因为要把数据显示在form表单中。
- action="orderConfirm.html"
- tbody标签的id="cart-list"属性,自动加载的内容需要体现在tbody中。
- type="button":结算按钮的submit改成button,后续需要传数据。
3.ready()函数来完成自动的ajax请求的提交和处理。
<script type="text/javascript">$(document).ready(function () {showCartList();});//展示购物车列表数据function showCartList() {$("#cart-list").empty();$.ajax({url: "/carts",type: "GET",dataType: "JSON",success: function(json) {let list = json.data;for (var i = 0; i < list.length; i++) {//用户所拿到的是一个list集合,在这个list集合中封装的是cartVO对象,在这里先拿到这个list集合let tr = '<tr>\n' +'<td>\n' + //在这里给复选框一个cid值,在往后点击结算的时候会把这个cid值传递给下个页面//把这个数据提交给另一个页面是以参数的形式提交,所以这个表单一定要有内部属性'<input name="cids" value="#{cid}" type="checkbox" class="ckitem" />\n' +'</td>\n' +'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +'<td>#{title}#{msg}</td>\n' +'<td>¥<span id="goodsPrice#{cid}">#{singlePrice}</span></td>\n' +'<td>\n' +'<input type="button" value="-" class="num-btn" οnclick="reduceNum(1)" />\n' +'<input id="goodsCount#{cid}" type="text" size="2" readonly="readonly" class="num-text" value="#{num}">\n' +'<input class="num-btn" type="button" value="+" οnclick="addNum(#{cid})" />\n' +'</td>\n' +'<td><span id="goodsCast#{cid}">#{totalPrice}</span></td>\n' +'<td>\n' +'<input type="button" οnclick="delCartItem(this)" class="cart-del btn btn-default btn-xs" value="删除" />\n' +'</td>\n' +'</tr>';tr = tr.replaceAll(/#{cid}/g, list[i].cid);tr = tr.replaceAll(/#{image}/g, list[i].image);tr = tr.replaceAll(/#{title}/g, list[i].title);tr = tr.replaceAll(/#{singlePrice}/g, list[i].realPrice);tr = tr.replaceAll(/#{num}/g, list[i].num);tr = tr.replaceAll(/#{totalPrice}/g, list[i].realPrice * list[i].num);if (list[i].realPrice < list[i].price) {tr = tr.replace(/#{msg}/g, "比加入时降价" + (list[i].price - list[i].realPrice) + "元");} else {tr = tr.replace(/#{msg}/g, "");}$("#cart-list").append(tr);}},error: function (xhr) {alert("加载购物车列表数据时产生未知的异常"+xhr.status);}});}</script>
🎃1. 增加购物车商品数量-持久层
✨1.1规划需要执行的SQL语句
1.执行更新t_cart表记录的num的值,无需重复开发。
update t_cart set num=#{num},modified_time={modifiedTime},modified_user=#{modifiedUser} where cid=#{cid}
2.根据cid查询购物车的这条记录是否存在。
select * from t_cart where cid=?
✨1.2设计接口和抽象方法
Cart findByCid(Integer cid);
✨1.3配置SQL映射
<select id="findByCid" resultMap="CartEntityMap">select * from t_cart where cid=#{cid}</select>
编写单元测试。
@Testpublic void findByCid(){System.out.println(cartMapper.findByCid(2));}
🎃 2.增加购物车商品数量-业务层
✨2.1规划异常
1.在更新时会产生更新异常。
2.查询到的数据是否有访问权限。
3.查询的数据不存在,抛出:CartNotFoundException异常。
public class CartNotFoundException extends ServiceException{public CartNotFoundException() {super();}public CartNotFoundException(String message) {super(message);}public CartNotFoundException(String message, Throwable cause) {super(message, cause);}public CartNotFoundException(Throwable cause) {super(cause);}protected CartNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
✨2.2设计接口和抽象方法
/*** 更新用户的购物车数据* @param cid * @param uid* @param username * @return 增加成功后新的数量*/Integer addNum(Integer cid,Integer uid,String username);
✨ 2.3实现方法
@Overridepublic Integer addNum(Integer cid, Integer uid, String username) {Cart result = cartMapper.findByCid(cid);if(result == null){throw new CartNotFoundException("数据不存在");}if(!result.getUid().equals(uid)){throw new AccessDeniedException("数据非法访问");}Integer num = result.getNum()+1;Integer rows = cartMapper.updateNumByCid(cid,num,username,new Date());if(rows != 1){throw new UpdateException("更新时产生异常");}//返回新的购物车总量return num;}
🎃 3.增加购物车商品数量-控制层
✨3.1处理异常
else if(e instanceof CartNotFoundException) {result.setState(4007);result.setMessage("购物车数据不存在的异常");}
✨3.2设计请求
请求路径:/carts/{cid}/num/add
请求方式:POST
请求数据:Integer cid,HttpSession session
响应结果:JsonResult<Integer>
✨3.3处理请求
@RequestMapping("{cid}/num/add")public JsonResult<Integer> addNum(Integer cid,HttpSession session){Integer data = cartService.addNum(cid,getuidFromSession(session),getUsernameFromSession(session));return new JsonResult<>(OK,data);}
先登录在访问url地址对应的地址。
🎃 4.增加购物车商品数量-前端页面
1.前面已经在onclick中改过里面的内容,所以无需重复修改了,但是需要重新编写addNum()以确保点击后能够增加数量。
<input class="num-btn" type="button" value="+" οnclick="addNum(#{cid})" />
function addNum(cid){$.ajax({url: "/carts/"+cid+"/num/add",type: "POST",dataType: "JSON",success: function (json) {if (json.state == 200) {//先拿到数量展示的id,$("#goodsCount"+cid).val(json.data)//由于price的值不是放在val控件上,也不是放在某一个属性上,通过html来拿,//html就是拿到它标签内部的这个东西,如果内部是个串拿到的就是个串//获取某个标签内部的内容:文本、标签//因为刚好这个内容即:singlePrice作为一个子内容放在了开始和结束的中间let price = $("#goodsPrice"+cid).html();let totalPrice = price * json.data;$("#goodsCast"+cid).html(totalPrice);} else {alert("增加购物车商品数量失败")}},error: function (xhr) {alert("增加购物车商品数量时产生未知的异常!"+xhr.message);}});}相关文章:
【基于SprintBoot+Mybatis+Mysql】电脑商城项目之加入购物车和显示购物车列表
🧸安清h:个人主页 🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】 🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。 目录 🚀1.加入购物车-数…...
再谈影刀RPA成长学习路线
近期,我将使用影刀RPA开发各电商平台移动端商品信息爬取,实战流程会在QQ群里分享,欢迎大家进群,一起探讨交流! 1. 影刀RPA学习路线概述 1.1 学习目标与意义 学习影刀RPA的目标在于掌握一种高效的工作自动化工具,以提…...
PHP-综合4
[题目信息]: 题目名称题目难度PHP-综合42 [题目考点]: PHP综合训练[Flag格式]: SangFor{Ouk3i63BuShgxqdRcn_9kMNqKFDe5j4f}[环境部署]: docker-compose.yml文件或者docker tar原始文件。 http://分配ip:2087[题目writeup]:…...
学习笔记-沁恒第五讲-米醋
一,设置音量 上次 这次 #include "uart.h" #include "debug.h" void audio_init() { Usart3_Init(); } void audio_play(u8 num) { u8 string[]{0x7e,0x05,0x41,0x00,num,0x05^0x41^0x00^num,0xef}; u8 i; for(i0;i<7;i) { USART_Se…...
【JavaScript】JavaScript 常见概念 - 变量与数据类型 - 运算符 - 条件语句 - 循环 - 函数 - 数组操作 - 对象
1. 变量与数据类型 变量声明 JavaScript 提供了三种方式来声明变量: var(全局或函数作用域,不推荐)let(块级作用域,推荐)const(常量,块级作用域,推荐&…...
Web自动化之Selenium添加网站Cookies实现免登录
在使用Selenium进行Web自动化时,添加网站Cookies是实现免登录的一种高效方法。通过模拟浏览器行为,我们可以将已登录状态的Cookies存储起来,并在下次自动化测试或爬虫任务中直接加载这些Cookies,从而跳过登录步骤。 Cookies简介 …...
AI手机的技术细节
前序:先说各个功能涉及到的技术,再说宏观系统架构。AI手机有这样几个做法,给手机侧边增加一个按键;把手机的语音助手做的很好,能够快速稳定的进行唤醒;通过特殊形式的触摸手机的曲面屏位置等来进行唤醒AI …...
10. 九转金丹炼矩阵 - 矩阵置零(标记优化)
哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的金丹谷,谷中有一座巨大的九转金丹炉,炉身闪烁着神秘的光芒。金丹炉的入口处有一块巨大的石碑,上面刻着一行文字:“欲破此炉,需以九转金丹之力,炼矩阵之零,标记优化定乾坤。” 哪吒定睛一看,石碑上还有…...
[实现Rpc] 客户端 | Requestor | RpcCaller的设计实现
目录 Requestor类的实现 框架 完善 onResponse处理回复 完整代码 RpcCaller类的实现 1. 同步调用 call 2. 异步调用 call 3. 回调调用 call Requestor类的实现 (1)主要功能: 客户端发送请求的功能,进行请求描述对服务器…...
Java 大视界 -- 深度洞察 Java 大数据安全多方计算的前沿趋势与应用革新(52)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
山东大学软件学院nosql实验三
实验题目: 用Java做简单查询(2学时) 实验内容 用API方式,做简单查询。 实验要求 在以下要求中选择至少2个,使用Java语言实现数据查询,最终把数据输出到前端界面。 (1)找出年龄小于20岁的所有学生 &…...
正态分布的奇妙性质:为什么奇数阶中心矩(odd central moments)为零?
正态分布的奇妙性质:为什么奇数阶矩为零? 正态分布(Normal Distribution)是统计学中最常见的分布之一,它的钟形曲线几乎无处不在,从身高体重到测量误差,都能看到它的影子。除了均值和方差这两个…...
【入门音视频】音视频基础知识
🌈前言🌈 这个系列在我学习过程中,对音视频知识归纳总结的笔记。因为音视频相关讲解非常稀少,所以我希望通过这个音视频系列,跟大家一起学习音视频,希望减少初学者在学习上的压力。同时希望也欢迎指出文章的…...
游戏引擎学习第120天
仓库:https://gitee.com/mrxiao_com/2d_game_3 上次回顾:周期计数代码 我们正在进行一个项目的代码优化工作,目标是提高性能。当前正在优化某个特定的代码片段,已经将其执行周期减少到48个周期。为了实现这一目标,我们设计了一个…...
【Qt之QQuickWidget】QML嵌入QWidget中
由于我项目开始使用Widgets,换公司后直接使用QML开发,没有了解过如何实现widget到qml过渡,恰逢面试时遇到一家公司希望从widget迁移到qml开发,询问相关实现,一时语塞,很尴尬,粗略研究并总结下。 对qwidget嵌…...
Vue 3 + Vite 项目中配置代理解决开发环境中跨域请求问题
在 Vue 3 Vite 项目中,配置代理是解决开发环境中跨域请求问题的常见方法。通过在 Vite 的配置文件中设置代理,可以将前端请求转发到后端服务器,从而避免浏览器的同源策略限制。 1. 创建 Vue 3 Vite 项目 首先,确保你已经安装了…...
Eureka、ZooKeeper 和 Nacos 之间的对比
Eureka、ZooKeeper 和 Nacos 都是分布式系统中常用的服务注册与发现工具,但它们的定位、功能和适用场景有所不同。作为一名开发者,理解它们之间的对比有助于选择合适的技术栈。以下从多个维度进行详细比较: 1. 基本概述 Eureka 来源ÿ…...
CSS中padding和margin属性的使用
在 HTML 中,padding 和 margin 是用于控制元素布局和间距的重要属性。 一、Padding(内边距) 定义:Padding 是指元素内容与元素边框之间的距离。它可以在元素内部创造出空白区域,使得内容不会紧贴着边框。 作用 增加元…...
【Python爬虫(49)】分布式爬虫:在新兴技术浪潮下的蜕变与展望
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取ÿ…...
网络安全-系统层攻击流程及防御措施
系统层攻击流程涉及多个阶段,攻击者通过逐步渗透以获取控制权或窃取数据。以下是详细的流程及防御措施: 1. 侦察(Reconnaissance) 信息收集: 主动扫描:使用工具如Nmap、Masscan扫描目标IP、开放端口、服务…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
