项目实战系列三: 家居购项目 第四部分

2024-09-08 13:28

本文主要是介绍项目实战系列三: 家居购项目 第四部分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

购物车

  • 🌳购物车
    • 🍆显示购物车
    • 🍆更改商品数量
    • 🍆清空购物车&&删除商品
  • 🌳生成订单

🌳购物车

需求分析
1.会员登陆后, 可以添加家居到购物车
2.完成购物车的设计和实现
3.每添加一个家居,购物车的数量+1, 并显示

程序框架图

在这里插入图片描述

1.新建src/com/zzw/furns/entity/CartItem.java, CartItem-家居项模型

/*** 购物车的一项就是某个家居数据* @author 赵志伟* @version 1.0*/
@SuppressWarnings({"all"})
public class CartItem {private Integer id;//编号private String name;//家居名private Integer count;//数量private BigDecimal price;//单价private BigDecimal totalPrice;//总价private String imagePath;//家具图片public CartItem() {}//有参构造器, getter, setter方法
}

2.Cart数据模型

在这里插入图片描述

3.新建src/com/zzw/furns/entity/Cart.java, 这里默认添加的数量是1

//Cart就是购物车, 包含多个CartItem
public class Cart {//使用HashMap来保存private Map<Integer, CartItem> items = new HashMap<>();public boolean isEmpty() {return items.size() == 0;}//Cart表示购物车, items表示购物车明细//添加家居[CartItem]到Cartpublic void addItem(CartItem cartItem) {CartItem item = items.get(cartItem.getId());//得到购物车里的商品项if (item == null) {//说明当前购物车还没有这个cartItemitems.put(cartItem.getId(), cartItem);} else {//购物车中有这个cartItemitem.setCount(item.getCount() + 1);//数量加1//修改总价//item.getPrice() => BigDecmal//item.getCount() => Integeritem.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));}}public Integer getTotalCount() {Integer totalCount = 0;//购物车商品的总数量Collection<CartItem> cartItems = items.values();for (CartItem cartItem : cartItems) {totalCount += cartItem.getCount();}return totalCount;}/*** 返回购物车的总价* @return*/public BigDecimal getCartTotalPrice() {BigDecimal cartTotalPrice = new BigDecimal(0);//遍历我们的itemsSet<Integer> keys = items.keySet();for (Integer id : keys) {CartItem item = items.get(id);//提醒, 一定要包add后的值, 重新赋给 cartTotalPrice, 这样才是累加.cartTotalPrice = cartTotalPrice.add(item.getTotalPrice());}return cartTotalPrice;}//todo  setter, getter方法, toString方法
}

4.测试src/com/zzw/furns/test/CartTest.java

public class CartTest {@Testpublic void addItem() {Cart cart = new Cart();cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000), new BigDecimal(1000)));cart.addItem(new CartItem(1, "java从入门到精通", 1, new BigDecimal(1000), new BigDecimal(1000)));cart.addItem(new CartItem(2, "数据结构与算法", 1, new BigDecimal(100), new BigDecimal(100)));System.out.println(cart);}
}

5.创建src/com/zzw/furns/web/CartServlet.java
cart是个引用, cart内容变了, session中也会跟着变

@WebServlet(urlPatterns = "/cartServlet")
public class CartServlet extends BasicServlet {private FurnService furnService = new FurnServiceImpl();//添加一个添加家居到购物车的方法protected void addItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {int id = DataUtils.parseInt(request.getParameter("id"), 1);//家居id//根据id获取对应的家居信息Furn furn = furnService.queryFurnById(id);//先把正常的逻辑走完, 再处理异常的情况HttpSession session = request.getSession();Cart cart = (Cart) session.getAttribute("cart");//得到购物车 有可能是空的,也有可能是上次的if (cart == null) {cart = new Cart();session.setAttribute("cart", cart);}//构建一条家居明细: id,家居名,数量, 单价, 总价//count类型为Integer, 不赋值默认值为nullCartItem cartItem = new CartItem(id, furn.getName(), 1, furn.getPrice(), furn.getPrice(), furn.getImagePath());//将家居明细加入到购物车中. 如果家居id相同,数量+1;如果是一条新的商品,那么就新增cart.addItem(cartItem);System.out.println("cart= " + cart);String referer = request.getHeader("referer");response.sendRedirect(referer);}
}

6.首页获取id请求后台

<button furnId="${furn/id}" title="Add To Cart" class="add-to-cart">AddTo Cart
</button>
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">window.onload = function () {$("button[title='Add To Cart']").click(function () {window.location.href = "cartServlet?action=addItem&id=" + $(this).attr("furnId");})}
</script>

7.首页购买的商品总数量 - totalCount会默认调用getTotalCount方法

<a href="#offcanvas-cart"class="header-action-btn header-action-btn-cart pr-0"><i class="icon-handbag"> 购物车</i><span class="header-action-num">${sessionScope.cart.totalCount}</span>
</a>

8.Cart类getTotalCount方法 - 错误写法
正确写法 - totalCount必须是局部变量, 否则会造成累加

public class Cart {private Integer totalCount = 0;//1 3 3//如果totalCount是全局变量, 将遵循这样的增长方式//次数   购物车数量   totalCount(=totalCount+购物车数量)// 1        1         1// 2        2         3// 3        3         6// 4        4         10// 5        5         15// 6        6         21// 7        7         28public Integer getTotalCount() {Collection<CartItem> cartItems = items.values();for (CartItem cartItem : cartItems) {totalCount += cartItem.getCount();}return totalCount;}
}

1.HashMap的数据实际上是存在HashMap$Node中的, Node是HashMap的内部类
2.keySet里的key, 实际上只是引用, 指向了HashMap$Node<k, v>对象中的k, 真正的key值是保存在HashMap的Node内部类中的(HashMap$Node)

🍆显示购物车

需求分析
1.查看购物车, 可以显示如下信息
2.选中了哪些家居, 名称, 数量, 金额
3.统计购物车共多少商品, 总价多少

程序框架图

在这里插入图片描述

代码实现
1.从资源包上传文件web/views/cart/cart.jsp

2.web/views/customer/index.jsp跳转购物车页面无响应 - 排错技巧展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

定位

在这里插入图片描述

3.显示家居项

<tbody>
<%--找到显示购物车项,  进行循环的items--%>
<c:if test="${not empty sessionScope.cart.items}"><%--1.sessionScope.cart.items => 取出的是HashMap<Integer, CartItem>2.所以通过foreach标签取出的每一个对象, 即entry是 HashMap<Integer, CartItem>的 k-v3.var其实就是 entry4.所以要取出cartItem对象, 是通过 entry.value取出--%><c:forEach items="${sessionScope.cart.items}" var="entry"><tr><td class="product-thumbnail"><a href="#"><img class="img-responsive ml-3"src="${entry.value.imagePath}"alt=""/></a></td><%--隐藏域--%><td hidden="hidden" class="product-name"><a href="#">${entry.key}</a></td><td class="product-name"><a href="#">${entry.value.name}</a></td><td class="product-price-cart"><span class="amount">$${entry.value.price}</span></td><td class="product-quantity"><div class="cart-plus-minus"><input class="cart-plus-minus-box" type="text" name="qtyButton"value="${entry.value.count}"/></div></td><td class="product-subtotal">$${entry.value.totalPrice}</td><td class="product-remove"><a href="#"><i>class="icon-close"></i></a></td></tr></c:forEach>
</c:if>
</tbody>

4.显示底部统计数据

<div class="row"><div class="col-lg-12"><div class="cart-shiping-update-wrapper"><h4>共${sessionScope.cart.totalCount}件商品 总价 ${sessionScope.cart.totalPrice}元</h4><div class="cart-shiping-update"><a href="#">购 物 车 结 账</a></div><div class="cart-clear"><button>继 续 购 物</button><a href="#">清 空 购 物 车</a></div></div></div>
</div>

🍆更改商品数量

需求分析
1.进入购物车, 可以修改购买数量
2.更新该商品项的金额
3.更新购物车商品数量和总金额

程序框架图

在这里插入图片描述

1.修改Cart购物车类

/*** 修改指定的CartItem的数量和总价, 根据传入的id 和 count* @param id* @param count*/
public void updateCount(int id, int count) {//传进来的更新后的数量CartItem cartItem = items.get(id);if (cartItem != null) {//如果得到cartItem//先更新数量cartItem.setCount(count);//再更新总价cartItem.setTotalPrice(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())));//set方法有可能对count进行了二次处理, 所里这里用getCount()比较安全}
}

2.修改src/com/zzw/furns/web/CartServlet.java,增加方法updateCount

/*** 更新某个cartItem的数量, 即更新购物车* @param req* @param resp* @throws ServletException* @throws IOException*/protected void updateCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int id = DataUtils.parseInt(req.getParameter("id"), 0);//家居id[默认0, 即使传错也不会影响数据]int count = DataUtils.parseInt(req.getParameter("count"), 1);//更新后的数量//获取session中的购物车HttpSession session = req.getSession();Cart cart = (Cart) session.getAttribute("cart");if (cart != null) {cart.updateCount(id, count);}//回到请求更新购物车的原页面String referer = req.getHeader("referer");resp.sendRedirect(referer);}

3.修改web/views/cart/cart.jsp

<%--某个js文件对 cart-plus-minus 做了事件处理--%>
<div class="cart-plus-minus" furnId="${entry.value.id}"><input class="cart-plus-minus-box" type="text" name="qtybutton"value="${entry.value.count}"/>
</div>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.修改web/views/cart/cart.jsp

<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript">window.onload = function () {var CartPlusMinus = $(".cart-plus-minus");CartPlusMinus.prepend('<div class="dec qtybutton">-</div>');CartPlusMinus.append('<div class="inc qtybutton">+</div>');$(".qtybutton").on("click", function() {var $button = $(this);var oldValue = $button.parent().find("input").val();if ($button.text() === "+") {var newVal = parseFloat(oldValue) + 1;} else {// Don't allow decrementing below zeroif (oldValue > 1) {var newVal = parseFloat(oldValue) - 1;} else {newVal = 1;}}$button.parent().find("input").val(newVal);//在这里书写我们的代码var furnId = $button.parent().attr("furnId");//在这里发出修改购物车的请求location.href = "cartServlet?action=updateCount&id=" + furnId + "&count=" + newVal;});}
</script>

🍆清空购物车&&删除商品

需求分析
1.进入购物车, 可以删除某商品
2.可以清空购物车
3.要求给出适当的确认信息

程序框架图

在这里插入图片描述

应用实例-删除商品

1.修改Cart购物车类

/*** 根据传入的id, 删除指定的购物车项* @param id*/
public void deleteItem(int id) {items.remove(id);
}

2.修改src/com/zzw/furns/web/CartServlet.java,增加方法delItem

protected void delItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//为了防止接收的id转化成数字时报错, 在工具类DataUtils中写一个方法int id = DataUtils.parseInt(req.getParameter("id"), 0);HttpSession session = req.getSession();Cart cart = (Cart) session.getAttribute("cart");if (cart != null) {cart.deleteItem(id);}//返回到请求删除购物车的页面String referer = req.getHeader("referer");resp.sendRedirect(referer);
}

3.修改web/views/cart/cart.jsp

$(".product-remove").click(function () {var furnName = $(this).attr("furnName");return confirm("确定要删除 " + furnName + " 家居项吗?");
})
<td class="product-remove" furnName="${entry.value.name}"><a href="cartServlet?action=delItem&id=${entry.value.id}"><i class="icon-close"></i></a>
</td>

清空购物车

1.修改Cart购物车类

//清空购物车
public void clear() {items.clear();
}

2.修改src/com/zzw/furns/web/CartServlet.java,增加方法clear

protected void clear(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//清空购物车Cart cart = (Cart) req.getSession().getAttribute("cart");if (cart != null) {cart.clear();}String referer = req.getHeader("referer");resp.sendRedirect(referer);
}

3.修改web/views/cart/cart.jsp

//清空购物车
$("a:contains('清 空 购 物 车')").click(function () {return confirm("确定要清空购物车吗?");
})
<a href="cartServlet?action=clear">清 空 购 物 车</a>

🌳生成订单

需求分析
1.进入购物车, 点击购物车结账
2.生成订单和订单项, 并更新商品的销量和库存
3.如果会员没有登陆, 先进入登陆页面, 完成登陆后再结账

程序框架图

在这里插入图片描述

1.创建order表

-- 创建家居网购需要的数据库和表
-- 删除数据库
DROP DATABASE IF EXISTS home_furnishing;-- 删除表
DROP TABLE `order`;-- 创建数据库
CREATE DATABASE home_furnishing;-- 切换
USE home_furnishing;-- 创建订单表
-- 每个字段应当使用 not null 来约束
-- 字段类型的设计, 应当和相关联表的字段类型相对应
-- 是否需要使用外键? 
-- 1.需要[可以从db层保证数据的一致性(早期hibernate框架要求必须使用外键)]
-- 2.不需要[外键对效率有影响, 应当从程序的业务层保证数据的一致性(推荐)]
CREATE TABLE `order` (id VARCHAR(60) PRIMARY KEY, -- 订单编号create_time DATETIME NOT NULL,-- 年月日 时分秒price DECIMAL(10,2) NOT NULL,-- 订单价格`status` TINYINT NOT NULL, -- 订单状态(1未发货 2已发货 3已结账)member_id INT NOT NULL -- 谁的订单
)CHARSET utf8 ENGINE INNODB;

2.创建order_item表

-- 创建家居网购需要的数据库和表
-- 删除数据库
DROP DATABASE IF EXISTS home_furnishing;-- 删除表
DROP TABLE order_item;-- 创建数据库
CREATE DATABASE home_furnishing;-- 切换
USE home_furnishing;-- 创建订单明细表
CREATE TABLE order_item (id INT PRIMARY KEY AUTO_INCREMENT, -- 订单明细id`name` VARCHAR(32) NOT NULL,-- 家居名`count` INT UNSIGNED NOT NULL,-- 数量price DECIMAL(10, 2) NOT NULL,-- 价格total_price DECIMAL(10, 2) NOT NULL,-- 订单项的总价格order_id VARCHAR(60) NOT NULL -- 订单编号
)CHARSET utf8 ENGINE INNODB;

3.新建实体类src/com/zzw/furns/entity/OrderItem.java, 订单明细表

public class OrderItem {private Integer id;private String name;private Integer count;private BigDecimal price;private BigDecimal totalPrice;private String orderId;public OrderItem() {}//有参构造器//getter方法, setter方法, toString方法
}

4.新建实体类src/com/zzw/furns/entity/Order.java, 订单表

public class Order {private String id;private Date createTime;private BigDecimal price;private Integer status;private Integer memberId;private List<OrderItem> items = new ArrayList<>();//计算订单的商品数, 供前端EL表达式使用public Integer getTotalCount() {Integer totalCount = 0;for (OrderItem orderItem : items) {totalCount += orderItem.getCount();}return totalCount;}//无参构造器public Order() {}//有参构造器//getter方法, setter方法, toString方法
}

5.新建src/com/zzw/furns/dao/OrderItemDao.java

public interface OrderItemDAO {public boolean saveOrderItem(OrderItem orderItem);
}

6.新建src/com/zzw/furns/dao/impl/OrderItemDaoImpl.java

public class OrderItemDAOImpl extends BasicDAO<OrderItem> implements OrderItemDAO {@Overridepublic boolean saveOrderItem(OrderItem orderItem) {String sql = "INSERT INTO order_item(id, `name`, `count`, price, total_price, order_id) " +"VALUES(?, ?, ?, ?, ?, ?)";int update = update(sql, orderItem.getId(), orderItem.getName(), orderItem.getCount(),orderItem.getPrice(), orderItem.getTotalPrice(), orderItem.getOrderId());return update > 0;}
}

7.测试, 新建src/com/zzw/furns/test/OrderItemDAOTest.java

public class OrderItemDAOTest {private OrderItemDAO orderItemDAO = new OrderItemDAOImpl();@Testpublic void saveOrderItem() {OrderItem orderItem = new OrderItem(null, "小台灯", 10,new BigDecimal(25), new BigDecimal(10).multiply(new BigDecimal(25)), "9");boolean b = orderItemDAO.saveOrderItem(orderItem);System.out.println(b);}
}

8.新建src/com/zzw/furns/dao/OrderDao.java

public interface OrderDAO {//将传入的order对象 保存到数据库order表public boolean saveOrder(Order order);
}

9.新建src/com/zzw/furns/dao/impl/OrderDaoImpl.java

public class OrderDAOImpl extends BasicDAO<Order> implements OrderDAO {@Overridepublic boolean saveOrder(Order order) {String sql = "INSERT INTO `order`(id, `create_time`, price, `count`, `status`, member_id) " +"VALUES(?, ?, ?, ?, ?, ?)";int update = update(sql, order.getId(), order.getCreateTime(), order.getPrice(), order.getCount(),order.getStatus(), order.getMemberId());return update > 0;}
}

10.测试, 新建src/com/zzw/furns/test/OrderDAOTest.java

public class OrderDAOTest {private OrderDAO orderDAO = new OrderDAOImpl();@Testpublic void saveOrder() {Order order = new Order(UUID.randomUUID().toString(), new Date(), new BigDecimal(22.00), 0, 123);boolean saveOrder = orderDAO.saveOrder(order);System.out.println(saveOrder);}
}

11.新建src/com/zzw/furns/service/OrderService.java

public interface OrderService {//1.生成订单//2.订单是根据cart来生成, cart对象在session. 通过web层, 传入saveOrder//3.订单和一个会员关联public String saveOrder(Cart cart, int memberId);
}

12.新建src/com/zzw/furns/service/impl/OrderServiceImpl.java

public class OrderServiceImpl implements OrderService {private OrderDAO orderDAO = new OrderDAOImpl();private OrderItemDAO orderItemDAO = new OrderItemDAOImpl();private FurnDAO furnDAO = new FurnDAOImpl();//在这里可以感受到javaee分层的好处. 在service层, 通过组合多个dao的方法,// 完成某个业务 慢慢体会好处@Overridepublic String saveOrder(Cart cart, int memberId) {//将cart购物车的数据以order和orderItem的形式保存到DB中//因为生成订单会操作多张表, 因此会涉及到多表事务的问题, ThreadLocal+Mysql事务机制+过滤器//1.通过cart对象, 构建一个对应的order对象//  先生成一个UUID, 表示当前的订单号, UUID是唯一的String orderId = UUID.randomUUID().toString();//订单idOrder order = new Order(orderId, new Date(), cart.getCartTotalPrice(), 0, memberId);//保存order到数据表orderDAO.saveOrder(order);//订单生成成功//通过cart对象, 遍历CartItem, 构建OrderItem对象, 并保存到对应的order_item表Map<Integer, CartItem> cartItems = cart.getItems();String orderItemId = "";for (CartItem cartItem : cartItems.values()) {//通过cartItem对象构建了orderItem对象OrderItem orderItem = new OrderItem(null, cartItem.getName(), cartItem.getCount(),cartItem.getPrice(), cartItem.getTotalPrice(), orderId);//保存orderItemDAO.saveOrderItem(orderItem);//更新furn表  saleNum销量 - inventory库存//(1) 获取furn对象Furn furn = furnDAO.queryFurnById(cartItem.getId());//(2) 更新furn对象的 saleNum销量 - inventory库存furn.setInventory(furn.getInventory() - cartItem.getCount());furn.setSaleNum(furn.getSaleNum() + cartItem.getCount());//(3) 更新到数据表furnDAO.updateFurn(furn);}//清空购物车cart.clear();return orderId;}
}

13.测试src/com/zzw/furns/service/impl/OrderServiceTest.java

public class OrderServiceTest {private OrderService orderService = new OrderServiceImpl();@Testpublic void saveOrder() {//构建一个Cart对象Cart cart = new Cart();cart.addItem(new CartItem(1, "书桌", 1, new BigDecimal(12), new BigDecimal(12)));cart.addItem(new CartItem(2, "电脑", 2, new BigDecimal(12), new BigDecimal(24)));cart.addItem(new CartItem(3, "鼠标", 3, new BigDecimal(12), new BigDecimal(36)));String ordId = orderService.saveOrder(cart, 12);System.out.println("ordId = " + ordId);}
}

14.新建src/com/zzw/furns/web/OrderServlet.java

public class OrderServlet extends BasicServlet {//定义属性private OrderService orderService = new OrderServiceImpl();/*** 生成订单* @param request* @param response* @throws ServletException* @throws IOException*/protected void saveOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession();//获取购物车Cart cart = (Cart) session.getAttribute("cart");//如果cart为空, 说明会员没有购买任何家居, 转发到首页//这里需要补充逻辑: 购物车在session里, 但没有家居数据if (cart == null || cart.isEmpty()) {//重定向, 请求转发后面的代码会继续执行response.sendRedirect(request.getContextPath());return;}//获取到登陆的member对象Member member = (Member) session.getAttribute("member");if (member == null) {//说明用户没有登录, 转发到登陆页面//重定向到登陆页面request.getRequestDispatcher("/views/member/login.jsp").forward(request, response);return;//直接返回}//可以生成订单String orderId = orderService.saveOrder(cart, member.getId());//订单, 订单明细已生成session.setAttribute("orderId", orderId);//订单id//使用重定向放入到checkout.jspresponse.sendRedirect(request.getContextPath() + "/views/order/checkout.jsp");}
}

15.新建web/views/order/checkout.jsp

16.测试src/com/zzw/furns/test/CartTest.java, 防止生成空订单

@Test
public void isEmpty() {Map<Object, Object> map = new HashMap<>();map.put("k", "v");map.clear();System.out.println(map == null);//falseSystem.out.println(map.size());//0
}

17.查看HashMap源码

public void clear() {Node<K,V>[] tab;modCount++;if ((tab = table) != null && size > 0) {//clear之后, size置为0size = 0;for (int i = 0; i < tab.length; ++i)tab[i] = null;}
}

18.修改web/views/cart/cart.jsp

<div class="cart-shiping-update"><a href="orderServlet?action=saveOrder">购 物 车 结 账</a>
</div><a class="active" href="index.jsp"><h4>订单已结算, 订单号-${sessionScope.orderId}</h4>
</a>

这篇关于项目实战系列三: 家居购项目 第四部分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148236

相关文章

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Python 中 requests 与 aiohttp 在实际项目中的选择策略详解

《Python中requests与aiohttp在实际项目中的选择策略详解》本文主要介绍了Python爬虫开发中常用的两个库requests和aiohttp的使用方法及其区别,通过实际项目案... 目录一、requests 库二、aiohttp 库三、requests 和 aiohttp 的比较四、requ

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

Python项目打包部署到服务器的实现

《Python项目打包部署到服务器的实现》本文主要介绍了PyCharm和Ubuntu服务器部署Python项目,包括打包、上传、安装和设置自启动服务的步骤,具有一定的参考价值,感兴趣的可以了解一下... 目录一、准备工作二、项目打包三、部署到服务器四、设置服务自启动一、准备工作开发环境:本文以PyChar

多模块的springboot项目发布指定模块的脚本方式

《多模块的springboot项目发布指定模块的脚本方式》该文章主要介绍了如何在多模块的SpringBoot项目中发布指定模块的脚本,作者原先的脚本会清理并编译所有模块,导致发布时间过长,通过简化脚本... 目录多模块的springboot项目发布指定模块的脚本1、不计成本地全部发布2、指定模块发布总结多模

SpringBoot项目删除Bean或者不加载Bean的问题解决

《SpringBoot项目删除Bean或者不加载Bean的问题解决》文章介绍了在SpringBoot项目中如何使用@ComponentScan注解和自定义过滤器实现不加载某些Bean的方法,本文通过实... 使用@ComponentScan注解中的@ComponentScan.Filter标记不加载。@C

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一