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

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列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

Spring Boot项目中结合MyBatis实现MySQL的自动主从切换功能

《SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能》:本文主要介绍SpringBoot项目中结合MyBatis实现MySQL的自动主从切换功能,本文分步骤给大家介绍的... 目录原理解析1. mysql主从复制(Master-Slave Replication)2. 读写分离3.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读