【图书管理系统】深度讲解:图书列表展示的后端实现、高内聚低耦合的应用、前端代码讲解
1.约定前后端交互接口
[请求]
/book/getListByPage
[参数]
currentPage=1&pageSize=10
[响应]
返回封装的result对象对应的Json数据
2. 整体逻辑
2.1 Controller的逻辑
(1)把接收的参数封装为PageRequest类,里面有属性:currentPage(当前的页码),pageSize(每页设置多少条数据),offset(起始数据的Id)
(2)在PageRequest类中设置构造函数,构造函数里面设置offset的值
(3)检查访问者是否为已登录的用户
(4)检验传来的参数PageResult对象的属性是否合理
(5)把参数传给Service层
2.2 Service层
(1)使用Mapper获取总数据的条数
(2)把得到的参数传给Mapper对应的方法,获取该页的数据
(3)把得到的数据进行处理
(4)返回该Controller
2.3 Mapper层
(1)实现一个方法:查询数据的总数据条数
(2)实现一个方法:使用limit 实现分页查询
3. 后端代码实现
3.1 分页的逻辑和封装的类
(1)假设每页10条数据,逻辑如下:
第一页,第1-10的数据
第二页,第11-20的数据
第三页,第21-30的数据…
(2)数据库中数据的索引是从0开始的,更新逻辑(假设每页10条数据):
第一页,索引为0-9的数据
第二页,索引为10-19的数据
第三页,索引为20-29的数据…
(3)要想实现这个功能, 从数据库中进行分页查询,我们要使用 LIMIT 关键字,格式为:limit 开始索引每页显示的条数(开始索引从0开始)
limit a,b
关键字:a是开始的索引,b是从a开始显示的条数
--第一页
select * from book_info limit 0,10;--第二页
select * from book_info limit 10,10;--第三页
select * from book_info limit 20,10;
观察以上SQL语句,发现: 开始索引⼀直在改变, 每每页显示条数是固定的
开始索引的计算公式: 开始索引 = (当前页码 - 1) * 每页显示条数
(3)从上述的分析得出,要实现一个分页的查询需要三个属性:当前页码、查询的条数、起始的索引
(4)创建一个类PageRequest,封装这三个属性。这三个属性的逻辑关系还需要另外的处理(开始索引 = (当前页码 - 1) * 每页显示条数),为了方便调用,直接在构造方法中实现三者的逻辑关系
@Data
public class PageRequest {// 请求的页数private int currentPage=1;//请求的该页条数private int pageSize=10;//开始的索引private int offset;public PageRequest(int currentPage){this.currentPage = currentPage;this.offset=(this.currentPage-1)* this.pageSize;}public PageRequest(){this.offset=(this.currentPage-1)*this.pageSize;}public PageRequest(int currentPage, int pageSize){this.currentPage=currentPage;this.pageSize=pageSize;this.offset=(this.currentPage-1)* this.pageSize;}//获取开始的索引public int getOffset(){return (this.currentPage-1)* this.pageSize;}
}
构造函数说明:
(1)当前端没有传来页码和该页的条数时,默认使用该类的缺省值
(2)当前端只传来页码而没有该页的条数时,默认使用每页10条数据。
(3)当前端传来页码和该页的条数时,进行逻辑处理求offset。
Controller、Service、传参PageRequest类:
3.2 Controller层
BookInfoController 类的getBookInfoListByPage方法:
@Slf4j
@RequestMapping("/book")
@RestController
public class BookInfoController {@Autowiredprivate BookInfoService bookInfoService;// 手动设置拦截用户@RequestMapping("/getBookInfoListByPage")public Result getBookInfoListByPage(PageRequest pageRequest, HttpSession session){log.info("Controller被调用");//验证是否认证UserInfo userInfo = (UserInfo)session.getAttribute(Constants.SESSION_USER_KEY);if(userInfo==null){Result result = new Result();result.setStatus(ResultStatus.UNLOGIN);return result;}else if(userInfo.getId()<0){Result result = new Result();result.setStatus(ResultStatus.UNLOGIN);}// 参数校验if(pageRequest.getPageSize()<1||pageRequest.getCurrentPage()<=0){Result result = new Result();result.setStatus(ResultStatus.FIAL);result.setErrorMessage("参数验证失败");return result;}PageResult<BookInfo> pageResult = null;try{pageResult = bookInfoService.getBookInfoListByPage(pageRequest);}catch(Exception e){log.error("查询翻页信息错误:" + e);}// Result result = new Result();
// result.setStatus(ResultStatus.SUCCESS);
// result.setData(pageResult);
//
// return result;return Result.success(pageResult);}
}
说明:
(1)验证是否已认证:如果没有该代码,在浏览器中直接诶搜索127.0.0.1:8080/book/getBookInfoListByPage
(未登录)也会出现图书列表,这是不符合安全设计的。获取session中的对应的用户对象,并检查该用户是否合规。
(2)参数校验:为了高内聚低耦合,封装了一个Result类,Result类中设置的有常用的属性。
(3)页面的结果:为了高内聚低耦合,封装了一个PageResult类,PageResult类中设置的有常用的页面属性。
2.3 PageResult 和 Result
2.3.1 PageResult
如果不设计PageResult类,获取该页的内容后,需要返回前端三个属性:
(1)total(该页数据的总条数);
(2)bookInfoList(该页的数据);
(3)pageRequest(前端的请求内容)。
后端想要一次性返回给前段上述三个属性使用类封装起来是最好的办法,也实现了高内聚低耦合的设计。
PageResult类:
@Data
public class PageResult<T> {//当前页数据的总条数private int total;//当前页的数据private List<T> bookInfoList;private PageRequest pageRequest;public PageResult(int count,List<T> bookInfoList, PageRequest pageRequest){this.total = count;this.bookInfoList = bookInfoList;this.pageRequest = pageRequest;}
}
为了实现了高内聚低耦合的设计,PageResult类设计为模板类;在创建构造函数中设计赋值。
Controller和Service使用PageResult对象:
2.3.2 Result
使用Result类创建的对象可以作为后端返回给前端的中间对象,PageResult类包含返回给前端数据的常用属性。
Result类:
public class Result {private ResultStatus status;private String ErrorMessage;private Object data;public static Result success(Object data){Result result = new Result();result.setStatus(ResultStatus.SUCCESS);// 赋值返回的数据result.data = data;return result;}public ResultStatus getStatus() {return status;}public void setStatus(ResultStatus status) {this.status = status;}public String getErrorMessage() {return ErrorMessage;}public void setErrorMessage(String errorMessage) {ErrorMessage = errorMessage;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}
}
说明:
(1)Object 是Java中所有类的根类(基类),使用它可以让 data 字段存储任意类型的数据
(2)status是枚举类ResultStatus 的对象,一共有三个状态:
200:成功–SUCCESS
-1:用户未登录–UNLOGIN
-2:异常或检验失败–FAIL
public enum ResultStatus {SUCCESS(200),UNLOGIN(-1),FIAL(-2);private Integer status;ResultStatus(Integer Status){this.status=Status;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}
}
2.4 Service 层
Service层是处理主要业务逻辑的,直接调用Mapper层
@Slf4j
@Service
public class BookInfoService {@Autowiredprivate BookInfoMapper bookInfoMapper;public PageResult<BookInfo> getBookInfoListByPage(PageRequest pageRequest) {if(pageRequest==null){return null;}//获取表中数据的总数Integer count = bookInfoMapper.queryBookInfoCount();//获取该页的数据List<BookInfo> bookInfoList = bookInfoMapper.queryBookInfoByPage(pageRequest);//根据status 修改 statusCNfor(BookInfo it : bookInfoList){// 使用枚举类设置图书的状态it.setStatusCN(BookInfoStatusEnum.getNameByCode(it.getStatus()).getName());
// if(it.getStatus()==0){
// it.setStatusCN("无效");
// } else if(it.getStatus()==1){
// it.setStatusCN("可借阅");
// }else{
// it.setStatusCN("不可借阅");
// }}// 创建PageResult对象返回给Controllerreturn new PageResult<BookInfo>(count,bookInfoList,pageRequest);}
}
说明:
(1)bookInfoMapper.queryBookInfoCount():获取数据的总条数
(2)queryBookInfoByPage(pageRequest):获取该页的数据
(3)it.setStatusCN(BookInfoStatusEnum.getNameByCode(it.getStatus()).getName()):BookInfoStatusEnum是一个枚举类,该枚举类设置的有图书的状态:
public enum BookInfoStatusEnum {DELETED(0,"已经删除"),NORMALL(1,"允许借阅"),FORBIDDEN(2,"禁止借阅");public static BookInfoStatusEnum getNameByCode(int code){switch(code) {case 0: return BookInfoStatusEnum.DELETED;case 1: return BookInfoStatusEnum.NORMALL;case 2: return BookInfoStatusEnum.FORBIDDEN;default:return BookInfoStatusEnum.FORBIDDEN;}}private int code;private String name;//构造函数BookInfoStatusEnum(int code, String name){this.code= code;this.name = name;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
枚举类中的方法getNameByCode是一个静态方法,接收的参数是整型(方便BookInfo的status属性传参),方法中设置switch–case(多条件分支控制的语句),根据传来的参数创建BookInfoStatusEnum对象。
2.5 Mapper层
Mapper直访问数据库,该功能下有两个主要的方法:
@Mapper
public interface BookInfoMapper {//每页的数据@Select("select id,book_name,author,count,price,publish,status," +"create_time,update_time from book_info "+"where status !=0 order by id asc limit #{offset},#{pageSize} ")List<BookInfo> queryBookInfoByPage(PageRequest pageRequest);//数据的总条数@Select("select count(*) from book_info where status!=0;")Integer queryBookInfoCount();
说明:
(1)queryBookInfoByPage方法主要使用关键字limit
来进行分页查询,offset是数据的开始id,pageSize是数据条数的数量。
(2)queryBookInfoCount方法用于查询数据的总条数。
4. 前端代码
book_list.html文件:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>图书列表展示</title><link rel="stylesheet" href="css/bootstrap.min.css"><link rel="stylesheet" href="css/list.css"><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/bootstrap.min.js"></script><script src="js/jq-paginator.js"></script></head><body><div class="bookContainer"><h2>图书列表展示</h2><div class="navbar-justify-between"><div><button class="btn btn-outline-info" type="button" onclick="location.href='book_add.html'">添加图书</button><button class="btn btn-outline-info" type="button" onclick="batchDelete()">批量删除</button></div></div><table><thead><tr><td>选择</td><td class="width100">图书ID</td><td>书名</td><td>作者</td><td>数量</td><td>定价</td><td>出版社</td><td>状态</td><td class="width200">操作</td></tr></thead><tbody></tbody></table><div class="demo"><ul id="pageContainer" class="pagination justify-content-center"></ul></div><script>getBookList();function getBookList() {$.ajax({// 获取参数url:"/book/getBookInfoListByPage"+ location.search,type:"get",success:function(result){if(result.status == "FAIL"){location.href = "login.html";//}if(result.status == "UNLOGIN"){location.href = "login.html";//}var finalHtml="";result = result.data;////加载列表for(var book of result.bookInfoList){//根据每一条记录去拼接,拼成一个<tr>内容</tr>finalHtml += '<tr>'finalHtml += '<td><input type="checkbox" name="selectBook" value="'+book.id+'" id="selectBook" class="book-select"></td>'finalHtml += '<td>'+book.id+'</td>'finalHtml += '<td>'+book.bookName+'</td>'finalHtml += '<td>'+book.author+'</td>'finalHtml += '<td>'+book.count+'</td>'finalHtml += '<td>'+book.price+'</td>'finalHtml += '<td>'+book.publish+'</td>'finalHtml += '<td>'+book.statusCN+'</td>'finalHtml += '<td><div class="op">'finalHtml += '<a href="book_update.html?bookId='+book.id+'">修改</a>'finalHtml += '<a href="javascript:void(0)" onclick="deleteBook('+book.id+')">删除</a>'finalHtml += '</div></td></tr>'}//展示console.log(finalHtml);//放到tbody中$("tbody").html(finalHtml)//翻页信息$("#pageContainer").jqPaginator({totalCounts: result.total, //总记录数pageSize: result.pageRequest.pageSize, //每页的个数visiblePages: 5, //可视页数currentPage: result.pageRequest.currentPage, //当前页码first: '<li class="page-item"><a class="page-link">首页</a></li>',prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',//页面初始化和页码点击时都会执行onPageChange: function (page, type) {console.log("第" + page + "页, 类型:" + type);if(type=="change"){location.href="book_list.html?currentPage="+page; //使用后端默认设置的每页数据量}//跳转// location.href="book_list.html?currentPage="+page;}});}});}function deleteBook(id) {var isDelete = confirm("确认删除?");if (isDelete) {//删除图书$.ajax({//..});}}function batchDelete() {var isDelete = confirm("确认批量删除?");if (isDelete) {//获取复选框的idvar ids = [];$("input:checkbox[name='selectBook']:checked").each(function () {ids.push($(this).val());});//发送请求,批量删除$.ajax({//..});}}</script></div>
</body></html>
ajax说明:
- 处理请求结果
if (result.status == "FAIL" || result.status == "UNLOGIN") {location.href = "login.html"; // 状态异常时跳转到登录页
}if(result.status == "UNLOGIN"){location.href = "login.html";//未登录时跳转到登录页
}
- 动态生成表格行
遍历 result.bookInfoList 中的每本图书,生成包含复选框、图书信息和操作按钮的表格行,把每个图书信息拼接一起。
var finalHtml = "";
result = result.data; // 提取核心数据(假设 result.data 包含 bookInfoList 和 total)for (var book of result.bookInfoList) {finalHtml += '<tr>'+ '<td><input type="checkbox" name="selectBook" value="' + book.id + '" class="book-select"></td>'+ '<td>' + book.id + '</td>'+ '<td>' + book.bookName + '</td>'+ '<td>' + book.author + '</td>'+ '<td>' + book.count + '</td>'+ '<td>' + book.price + '</td>'+ '<td>' + book.publish + '</td>'+ '<td>' + book.statusCN + '</td>'+ '<td><div class="op">'+ '<a href="book_update.html?bookId=' + book.id + '">修改</a>'+ '<a href="javascript:void(0)" onclick="deleteBook(' + book.id + ')">删除</a>'+ '</div></td></tr>';
}$("tbody").html(finalHtml); // 将拼接的 HTML 插入表格
- 初始化分页控件 (jqPaginator)
$("#pageContainer").jqPaginator({totalCounts: result.total, // 总记录数pageSize: result.pageRequest.pageSize, // 每页显示数量visiblePages: 5, // 显示的分页按钮数currentPage: result.pageRequest.currentPage, // 当前页码// 分页按钮模板first: '<li class="page-item"><a class="page-link">首页</a></li>',prev: '<li class="page-item"><a class="page-link">上一页</a></li>',next: '<li class="page-item"><a class="page-link">下一页</a></li>',last: '<li class="page-item"><a class="page-link">末页</a></li>',page: '<li class="page-item"><a class="page-link">{{page}}</a></li>',// 页码变化回调onPageChange: function (page, type) {if (type == "change") { // 仅在用户点击时跳转location.href = "book_list.html?currentPage=" + page;}}
});
分页参数依赖后端返回的 total(总记录数)、pageRequest.pageSize(每页大小)、pageRequest.currentPage(当前页)。当用户点击分页按钮(类型为 “change”)时,通过修改 URL 的 currentPage 参数重新加载页面。
5.结语
本文系统讲解了基于 Spring Boot 和 MyBatis 的分页查询功能实现方案,从前端交互到数据库查询构建了完整的技术链路。通过 模块化封装 与 动态参数处理,实现了高复用性、易维护的分页架构,为数据密集型系统的开发提供了标准化解决方案。
核心价值:
-
分层解耦设计
通过 PageRequest 参数封装、PageResult 分页结果包装、Result 统一响应体,实现前后端数据流的规范化传递。 -
高效分页机制
基于 MySQL 的 LIMIT 分页语法,结合后端动态计算偏移量,有效平衡性能与开发效率。 -
安全与健壮性
参数校验、登录态拦截、异常捕获三重机制保障系统稳定性,避免非法请求与空指针异常。 -
前端交互友好
整合 jqPaginator 分页控件,实现页码动态渲染与无刷新跳转,提升用户体验。
相关文章:

【图书管理系统】深度讲解:图书列表展示的后端实现、高内聚低耦合的应用、前端代码讲解
1.约定前后端交互接口 [请求] /book/getListByPage [参数] currentPage1&pageSize10 [响应] 返回封装的result对象对应的Json数据 2. 整体逻辑 2.1 Controller的逻辑 (1)把接收的参数封装为PageRequest类,里面有属性:curren…...
Github 2025-05-10 Rust开源项目日报 Top10
根据Github Trendings的统计,今日(2025-05-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目1Python项目1Zed: 由Atom和Tree-sitter的创建者开发的高性能多人代码编辑器 创建周期:1071 天开发语言:Rust协议类型…...
drf 使用jwt
安装jwt pip install pyJwt 添加登录url path("jwt/login",views.JwtLoginView.as_view(),namejwt-login),path("jwt/order",views.JwtOrderView.as_view(),namejwt-order), 创建视图 from django.contrib.auth import authenticateimport jwt from jw…...

养生:为健康生活添彩
养生是对生活的热爱,是为健康生活注入活力的良方。从饮食、运动到生活习惯,每一个方面都能让我们离健康更近一步。以下是一些实用的养生之道,助你开启健康生活的新旅程。 饮食养生:营养均衡,健康基石 合理的饮食是养…...
在 Vue 3 中使用 canvas-confetti 插件
🎉 在 Vue 3 中使用 canvas-confetti 插件 canvas-confetti 是一个轻量、无依赖的 JavaScript 动画库,用于在网页上展示彩带、庆祝动画。非常适合用于抽奖、支付成功、活动庆祝等场景。 本教程将指导你如何在 Vue 3 项目中集成并使用该插件。 …...
rt-thread+STM32H7移植lwip出现问题解决方法
问题一:ping不通,或有丢帧情况。 问题二:不开启优化一切正常,keil开启优化后就无法联网。 问题三:网络断断续续。 解决方法: 主要是mpu配置和drv_eth驱动的问题,我的配置如下: mpu&…...
Java Spring、Spring MVC、Spring Boot 和 Spring Cloud 的关系与区别
在 Java 开发领域,Spring、Spring MVC、Spring Boot 和 Spring Cloud 这些框架和技术名词频繁出现。对于初学者来说,理解它们之间的关系和区别可能有些困惑。本文将深入浅出地讲解这些概念,帮助你理清它们的联系与差异。 一、Spring 1.1 定义 Spring 是一个轻量级的 Java…...

服务器综合实验(实战详解)
该文章的目录部分 实验内容 实验完成步骤 虚拟机准备 配置两个虚拟机的本地仓库 虚拟机A: 虚拟机B: 配置SSH公钥互信 虚拟机A: 编辑 虚拟机B: 提供基于bind的DNS服务 虚拟机A: 项目需求1: …...
Milvus 向量数据库详解与实践指南
一、Milvus 核心介绍 1. 什么是 Milvus? Milvus 是一款开源、高性能、可扩展的向量数据库,专门为海量向量数据的存储、索引和检索而设计。它支持近似最近邻搜索(ANN),适用于图像检索、自然语言处理(NLP&am…...
react+ts中函数组件父子通信方式
1. 父组件通过 Props 向子组件传递数据 这是最常见也是最基本的父子组件通信方式。父组件通过 props 将数据或回调函数传递给子组件。 示例代码: // 子组件接收来自父组件的数据 interface ChildProps {message: string; }const ChildComponent: React.FC<Chi…...

VSCode-插件:codegeex:ai coding assistant / 清华智普 AI 插件
一、官网 https://codegeex.cn/ 二、vscode 安装插件 点击安装即可,无需复杂操作,国内软件,无需科学上网,非常友好 三、智能注释 输入 // 或者 空格---后边自动出现注释信息,,按下 Tab 键,进…...

SlideLoss与FocalLoss在YOLOv8分类损失中的应用及性能分析
文章目录 一、引言二、YOLOv8 损失函数概述三、SlideLoss 详解(一)SlideLoss 的原理(二)SlideLoss 的代码实现 四、FocalLoss 分类损失函数详解(一)FocalLoss 的原理(二)FocalLoss 的…...
【AI智能推荐系统】第七篇:跨领域推荐系统的技术突破与应用场景
第七篇:跨领域推荐系统的技术突破与应用场景 提示语:🔥 “打破数据孤岛,实现1+1>2的推荐效果!深度解析美团、亚马逊如何用跨领域推荐技术实现业务协同,知识迁移核心技术全公开!” 目录 跨领域推荐的商业价值跨领域推荐技术体系 2.1 基于共享表征的学习2.2 迁移学习…...
ui组件二次封装(vue)
组件二次封装的意义 保证一个系统中ui风格和功能的一致性便于维护 从属性、事件、插槽、ref这几方面考虑 属性和事件的处理:ui组件上绑定$attrs(v-model本质也是一个属性加一个事件,所以也在其列) 在自定义组件中打印$attrs&am…...

OpenCv实战笔记(4)基于opencv实现ORB特征匹配检测
一、原理作用 ORB 原理(Oriented FAST and Rotated BRIEF): 特征点检测:使用 FAST 算法检测角点(关键点)。 方向计算:为每个关键点分配主方向,增强旋转不变性。 特征描述:…...
PyTorch 线性回归模型构建与神经网络基础要点解析
笔记 1 PyTorch构建线性回归模型 1.1 创建数据集 import torch from torch.utils.data import TensorDataset # 创建x和y张量数据集对象 from torch.utils.data import DataLoader # 创建数据集加载器 import torch.nn as nn # 损失函数和回归函数 from torch.optim impo…...
Android平台FFmpeg音视频开发深度指南
一、FFmpeg在Android开发中的核心价值 FFmpeg作为业界领先的多媒体处理框架,在Android音视频开发中扮演着至关重要的角色。它提供了: 跨平台支持:统一的API处理各种音视频格式完整功能链:从解码、编码到滤镜处理的全套解决方案灵…...

深入解析路由策略:从流量控制到策略实施
一、网络流量双平面解析 在路由策略的设计中,必须明确区分两个关键平面: 1. 控制层面(Control Plane) 定义:路由协议传递路由信息形成的逻辑平面(如OSPF的LSA、RIP的Response报文)…...

FHE 之 面向小白的引导(Bootstrapping)
1. 引言 FHE初学者和工程师常会讨论的一个问题是; “什么是引导(bootstrapping)?” 从理论角度看,这个问题的答案很简单: 引导就是套用 Gentry 提出的思想——在加密状态下同态地执行解密操作ÿ…...

51单片机入门教程——AT24C02数据存储
前言 本教程基于B站江协科技课程进行个人学习整理,专为拥有C语言基础的零基础入门51单片机新手设计。既帮助解决因时间差导致的设备迭代调试难题,也助力新手快速掌握51单片机核心知识,实现从C语言理论到单片机实践应用的高效过渡 。 目录 …...

M0的基础篇之PWM学习
一、困惑 上一节课就是单纯的之配置了一个基础的定时器进行计数,计到一定的数值也就是到了一定的时间就进入中断,执行中断里面的任务,也就是一个最基础的定时的功能 这一节课的定时器产生了一个pwm波。也就是我们可以改变里面高电平的持续时间…...

Python----神经网络(基于AlexNet的猫狗分类项目)
一、基于AlexNet的猫狗分类 1.1、项目背景 猫和狗是我们生活中最常见的宠物,它们的图像数据大量存在于互联网上。对此进行分类不仅可以帮助开发自动化宠物识别应用,也可以应用于更广泛的计算机视觉领域。例如,训练良好的模型可以支持流浪动物…...
excel表数据导入数据库
前两天,有个两DB之间的数据导出导入的需求。对方提供的是excel表,我这边是mysql数据库,excel表第一行是字段名,之后的行是记录的值。 其实没有多复杂,我先将exel转成csv,结果mysql导入csv,第一行…...
SMT贴片钢网精密设计与制造要点解析
内容概要 SMT贴片钢网作为电子组装工艺的核心载体,其设计与制造质量直接影响焊膏印刷精度及产品良率。本文系统梳理了钢网全生命周期中的15项关键技术指标,从材料选择、结构设计到工艺控制构建完整技术框架。核心要点涵盖激光切割精度的微米级调控、开口…...
第三节:条件语句与循环:控制程序流程
📌 第三节:条件语句与循环:控制程序流程 目标:熟练运用条件判断、循环结构,实现动态逻辑与重复操作,掌握常见算法的底层实现。 一、条件语句:让程序“聪明”起来 1. if-else 基础语法 作用&am…...

荣耀A8互动娱乐组件部署实录(第1部分:服务端环境搭建)
作者:一位被“只支持安卓”的前端劝退过三次的技术人 前言 这一套组件我拆包已经不止一遍了,老实讲,不支持 iOS 是遗憾,但对于研究 UI 动态加载、资源分离结构和整体架构来说,A8 的这套服务还算完整,服务器…...
流式渲染 Streaming SSR
以下是关于流式渲染(Streaming SSR)的基本知识点总结: 一、流式渲染核心概念 1. 与传统SSR对比 维度传统SSR流式SSR响应方式完整HTML生成后一次性返回分块逐步返回HTML内容首字节时间较慢(需等待所有数据处理完成)极快(立即发送初始HTML结构)内存压力高(需缓存完整页面…...

基于Python Flask的深度学习电影评论情感分析可视化系统(2.0升级版,附源码)
博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇dz…...
如何减少极狐GitLab 容器镜像库存储?
极狐GitLab 是 GitLab 在中国的发行版,关于中文参考文档和资料有: 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 减少容器镜像库存储 (BASIC ALL) 未清理的容器镜像库会随着时间的推移而变大。添加大量镜像或标签时: 获取可用标…...

计算机学习路线与编程语言选择(信息差)
——授人以鱼不如授人以渔 计算机学习公式:1/3科班思维 1/3路线选择 1/3工程能力 好工作随便找(来自B站小毛毛熊) 本文主要是路线选择!!!下面开始吧。 面向岗位学习!到招聘网站看看有哪些…...