当前位置: 首页 > news >正文

【图书管理系统】深度讲解:图书列表展示的后端实现、高内聚低耦合的应用、前端代码讲解

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说明:

  1. 处理请求结果​
if (result.status == "FAIL" || result.status == "UNLOGIN") {location.href = "login.html"; // 状态异常时跳转到登录页
}if(result.status == "UNLOGIN"){location.href = "login.html";//未登录时跳转到登录页
}
  1. 动态生成表格行​
    遍历 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 插入表格
  1. 初始化分页控件 (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 的分页查询功能实现方案,从前端交互到数据库查询构建了完整的技术链路。通过 ​​模块化封装​​ 与 ​​动态参数处理​​,实现了高复用性、易维护的分页架构,为数据密集型系统的开发提供了标准化解决方案。

​​核心价值​​

  1. ​​分层解耦设计​​
    通过 PageRequest 参数封装、PageResult 分页结果包装、Result 统一响应体,实现前后端数据流的规范化传递。

  2. 高效分页机制​​
    基于 MySQL 的 LIMIT 分页语法,结合后端动态计算偏移量,有效平衡性能与开发效率。

  3. 安全与健壮性​​
    参数校验、登录态拦截、异常捕获三重机制保障系统稳定性,避免非法请求与空指针异常。

  4. 前端交互友好​​
    整合 jqPaginator 分页控件,实现页码动态渲染与无刷新跳转,提升用户体验。

相关文章:

【图书管理系统】深度讲解:图书列表展示的后端实现、高内聚低耦合的应用、前端代码讲解

1.约定前后端交互接口 [请求] /book/getListByPage [参数] currentPage1&pageSize10 [响应] 返回封装的result对象对应的Json数据 2. 整体逻辑 2.1 Controller的逻辑 &#xff08;1&#xff09;把接收的参数封装为PageRequest类&#xff0c;里面有属性&#xff1a;curren…...

本地大模型工具深度评测:LM Studio vs Ollama,开发者选型指南

引言 在大语言模型本地化部署的技术浪潮中&#xff0c;隐私保护与成本优化成为核心诉求。LM Studio与Ollama作为两款明星级本地大模型工具&#xff0c;凭借对开源模型的支持能力&#xff0c;成为开发者关注的焦点。本文将从技术架构、应用场景、实操体验三个维度展开深度对比&a…...

天线的PCB设计

目录 天线模块设计的重要性 天线模块的PCB设计 天线模块设计的重要性 当智能手表突然断连、无人机信号飘忽不定——你可能正在经历一场来自天线模块的"无声抗议"。这个隐藏在电子设备深处的关键组件&#xff0c;就像数字世界的隐形信使&#xff0c;用毫米级的精密结…...

《P1226 【模板】快速幂》

题目描述 给你三个整数 a,b,p&#xff0c;求 abmodp。 输入格式 输入只有一行三个整数&#xff0c;分别代表 a,b,p。 输出格式 输出一行一个字符串 a^b mod ps&#xff0c;其中 a,b,p 分别为题目给定的值&#xff0c; s 为运算结果。 输入输出样例 输入 #1复制 2 10 9输…...

推荐一款免费开源工程项目管理系统软件,根据工程项目全过程管理流程开发的OA 办公系统

在当今的工程项目管理领域&#xff0c;许多企业和团队面临着诸多难题。传统的管理方式往往依赖于人工记录和分散的工具&#xff0c;导致项目进度难以实时把控&#xff0c;任务分配不够清晰&#xff0c;合同管理混乱&#xff0c;事件提醒不及时&#xff0c;财务管理缺乏系统性&a…...

AZScreenRecorder最新版:功能强大、操作简便的手机录屏软件

AZScreenRecorder最新版是一款功能强大的手机录屏软件&#xff0c;专为安卓设备设计。它无需ROOT权限&#xff0c;支持无限录制时长&#xff0c;操作简单&#xff0c;录制过程中可以随时暂停&#xff0c;满足不同用户的个性化录屏需求。此外&#xff0c;用户还可以自定义分辨率…...

[sklearn机器学习概述]机器学习-part3

获取数据、数据处理、特征工程后&#xff0c;就可以交给预估器进行机器学习&#xff0c;流程和常用API如下。 1.实例化预估器(估计器)对象(estimator)&#xff0c; 预估器对象很多,都是estimator的子类&#xff08;1&#xff09;用于分类的预估器sklearn.neighbors.KNeighbors…...

[模型选择与调优]机器学习-part4

七 模型选择与调优 1 交叉验证 (1) 保留交叉验证HoldOut HoldOut Cross-validation&#xff08;Train-Test Split&#xff09; 在这种交叉验证技术中&#xff0c;整个数据集被随机地划分为训练集和验证集。根据经验法则&#xff0c;整个数据集的近70%被用作训练集&#xff…...

PyTorch API 1 - 概述、数学运算、nn、实用工具、函数、张量

文章目录 torch张量创建操作索引、切片、连接与变异操作 加速器生成器随机采样原地随机采样准随机采样 序列化并行计算局部禁用梯度计算数学运算常量逐点运算归约操作比较运算频谱操作其他操作BLAS 和 LAPACK 运算遍历操作遍历操作遍历操作遍历操作遍历操作遍历操作遍历操作遍历…...

如何在mac上使用便利贴

可以在 App Store 下载便利贴应用实现在电脑上贴便条的效果。 以 「桌面便利贴」这款应用为例&#xff0c;创建的便利贴会像桌面上的文件一样展示在桌面上&#xff0c;随时可以查看。还可以修改便笺的颜色、透明度、字体、高亮等等。 我比较喜欢的功能是将便签固定在所有窗口的…...

Linux——Mysql索引和事务

目录 一&#xff0c;Mysql索引介绍 1&#xff0c;索引概述 1&#xff0c;索引的优点 2&#xff0c;索引的缺点 2&#xff0c;索引作用 3&#xff0c;索引分类 普通索引 唯一索引 主键索引 组合索引 全文索引 4&#xff0c;查看索引 5&#xff0c;删除索引 6&…...

vim 查看复杂的宏扩展

在一些复杂项目中&#xff0c;使用宏可以简化代码。但是对于刚接触项目的人来说&#xff0c;分析层层嵌套的宏&#xff0c;是件头疼的事情。 使用 vim 的多窗口功能&#xff0c;可以为此提供一些帮助。 如下图&#xff0c;分析4层嵌套的宏&#xff0c;DEFINE_I440FX_MACHINE -…...

【计算机视觉】OpenCV项目实战:基于OpenCV的图像分割技术深度解析与实践指南

基于OpenCV的图像分割技术深度解析与实践指南 项目概述与技术背景项目核心特点传统分割算法分类 环境配置与项目结构系统要求安装步骤项目结构解析 核心算法实现解析1. 阈值分割&#xff08;Otsu方法&#xff09;2. Canny边缘检测3. 分水岭算法 实战应用指南1. 基础分割流程2. …...

线性表-顺序表(Sequential List)

1 线性表 1.1 顺序表&#xff08;Sequential List&#xff09; 顺序表并不难理解&#xff0c;主要是知道顺序表是在内存中连续存储的一段数据&#xff0c;知道这个后&#xff0c;相应的算法也就非常简单了。 线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的…...

《用MATLAB玩转游戏开发:从零开始打造你的数字乐园》基础篇(2D图形交互)-俄罗斯方块:用旋转矩阵打造经典

《用MATLAB玩转游戏开发&#xff1a;从零开始打造你的数字乐园》基础篇&#xff08;2D图形交互&#xff09;-&#x1f3ae; 俄罗斯方块&#xff1a;用旋转矩阵打造经典 &#x1f9ca; 大家好&#xff01;今天我将带大家用MATLAB实现经典的俄罗斯方块游戏。我们将从数学原理出发…...

通过user-agent来源判断阻止爬虫访问网站,并防止生成[ error ] NULL日志

一、TP5.0通过行为&#xff08;Behavior&#xff09;拦截爬虫并避免生成 [ error ] NULL 错误日志 1. 创建行为类&#xff08;拦截爬虫&#xff09; 在 application/common/behavior 目录下新建BlockBot.php &#xff0c;用于识别并拦截爬虫请求&#xff1a; <?php name…...

微服务的“迷宫” - 我们为何需要服务网格?

微服务的“迷宫” - 我们为何需要服务网格? 你好!欢迎来到我们的服务网格探索之旅。近年来,“微服务架构”无疑是软件开发领域最热门的词汇之一。它将庞大的单体应用拆分成一组小而独立的、可以独立开发、部署和扩展的服务单元,带来了前所未有的敏捷性和弹性。开发团队可以…...

Ubuntu 安装 HAProxy

HAProxy 是什么 HAProxy&#xff08;High Availability Proxy&#xff09; 是一个 高性能、高可用的 TCP 和 HTTP 负载均衡器与代理服务器。 HAProxy 的特点 特性说明支持协议HTTP、HTTPS、TCP高性能使用 C 语言编写&#xff0c;性能极高高可用与 Keepalived 配合可实现主备健…...

VUE CLI - 使用VUE脚手架创建前端项目工程

前言 前端从这里开始&#xff0c;本文将介绍如何使用VUE脚手架创建前端工程项目 1.预准备&#xff08;编辑器和管理器&#xff09; 编辑器&#xff1a;推荐使用Vscode&#xff0c;WebStorm&#xff0c;或者Hbuilder&#xff08;适合刚开始练手使用&#xff09;&#xff0c;个…...

Nginx高级配置

目录 一.网页的状态页 二. Nginx第三方模块 2.1 echo模块 三. 变量 3.1 内置变量 3.2 自定义变量 四. 自定义访问日志 (优化) 4.1 自定义访问日志的格式 4.2 自定义json 格式日志 五. Nginx压缩功能 六 . HTTPS 功能 6.1 https概述 6.2 配置实例-----自签名证…...

Docker镜像搬运工:深入解析export与import,实现容器环境无缝迁移!

Docker作为现代开发运维的利器&#xff0c;其镜像和容器的管理技巧直接影响效率。当我们需要跨环境迁移容器状态时&#xff0c;docker export和docker import这对组合命令就能大显身手。本文带你彻底搞懂它们的核心逻辑、使用场景及避坑指南&#xff01; 一、Docker export&…...

数字孪生实战笔记(1)数字孪生的含义、应用及技术体系

一、含义 数字孪生&#xff08;Digital Twin&#xff09;是一种通过数字化模型在虚拟世界中实时映射和模拟物理实体、系统或过程的技术。它的核心目的是通过对现实对象的建模、感知、分析和预测&#xff0c;实现对物理世界的全面感知、智能控制和优化决策。数字孪生 实体对象 …...

计算机网络 4-2-2 网络层(IPv4)

2.7 网络地址转换NAT 引入端口号&#xff1a;IP地址端口号→一个特定的进程&#xff0c;&#xff08;不同主机可能存在相同端口号&#xff09; 网络层实现了“主机到主机”的通信。网络层在IP数据报的首部&#xff0c;指明源IP地址、目的IP地址 传输层实现了“端到端” &#…...

第二个简单的SpringBoot和Vue前后端全栈的todoapp案例

项目源于哔哩哔哩&#xff0c;按视频手敲了一下&#xff0c;补充上代码和一些细节。 全栈项目实践&#xff1a;1小时快速入门SpringBootvue3element-plus_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LH4y1w7Nd/?spm_id_from333.1387.favlist.content.click&vd_…...

探秘 Canva AI 图像生成器:重塑设计创作新范式

Canva 凭借简洁易用的界面和海量模板资源&#xff0c;早已成为设计师和普通用户的心头好。而 Canva AI 图像生成器的推出&#xff0c;更是为设计领域带来了一场深刻变革&#xff0c;以智能化的手段重塑了图像创作的方式与边界。 技术内核&#xff1a;AI 如何驱动图像生成 Can…...

栈应用:辅助站(c++)

干货 今天讲讲最大辅助栈和最小辅助栈 主栈进入元素的时候 最大辅助栈:保证新元素大于等于(辅助栈)顶的时候&#xff0c;再进入辅助栈这样就能保证最大辅助栈的栈顶元素 是主栈中的最大值 主栈出栈的时候 最大辅助栈:主栈出栈元素如果等于(辅助栈)的栈顶元素&#xff0c;再…...

AI时代的数据可视化:未来已来

你有没有想过&#xff0c;数据可视化在未来会变成什么样&#xff1f;随着人工智能&#xff08;AI&#xff09;的飞速发展&#xff0c;数据可视化已经不再是简单的图表和图形&#xff0c;而是一个充满无限可能的智能领域。AI时代的可视化不仅能自动解读数据&#xff0c;还能预测…...

常见音频主控芯片以及相关厂家总结

音频主控芯片是音频设备&#xff08;如蓝牙耳机、音箱、功放等&#xff09;的核心组件&#xff0c;负责音频信号的解码、编码、处理和传输。以下是常见的音频主控芯片及其相关厂家&#xff0c;按应用领域分类&#xff1a; 蓝牙音频芯片 主要用于无线耳机、音箱等设备&#xff0…...

湖仓一体架构在金融典型数据分析场景中的实践

在数字经济与金融科技深度融合的今天&#xff0c;数据已成为金融机构的核心战略资产。然而&#xff0c;传统数据架构面临着三大困局&#xff0c;制约着金融机构数据价值的充分释放。 一、需求驱动更多银行数据分析场景 金融机构&#xff0c;特别是银行业&#xff0c;面临着双重…...

VBA —— 学习Day5

子程序与函数 子程序&#xff1a;实现特定功能的程序代码块 子程序语法&#xff1a; [修饰符] Sub 子程序名称([参数1&#xff0c;参数2&#xff0c;参数3]) 代码块 End Sub 子程序如何调用&#xff1a; 1 . 子程序名 [参数1&#xff0c;参数2&#xff0c;...] 2. Cal…...

Flink 实时数据一致性与 Exactly-Once 语义保障实战

在构建企业级实时数仓的过程中,“数据一致性” 是保障指标准确性的核心能力,尤其是在金融、电商、医疗等对数据敏感度极高的场景中。Flink 作为流批一体的实时计算引擎,其内建的 Exactly-Once 语义为我们提供了强有力的保障机制。本篇将围绕如何实现端到端的数据一致性、如何…...

Java云原生到底是啥,有哪些技术

☁️ Java云原生&#xff1a;程序员の修仙飞升指南&#xff08;附渡劫技巧&#xff09; 一、修仙世界观&#xff1a;传统程序 vs 云原生程序 &#x1f3e1; 传统Java程序&#xff08;老宅院&#xff09; 特点&#xff1a;单体大瓦房、扩建要拆墙&#xff08;耦合度高&#xf…...

IPM IMI111T-026H 高效风扇控制板

概述&#xff1a; REF-MHA50WIMI111T 是一款专为风扇驱动设计的参考开发板&#xff0c;搭载了英飞凌的IMI111T-026H iMOTION™智能功率模块(IPM)。这个模块集成了运动控制引擎(MCE)、三相栅极驱动器和基于IGBT的功率级&#xff0c;全部封装在一个紧凑的DSO22封装中。REF-MHA50…...

JavaScript基础-局部作用域

在JavaScript中&#xff0c;理解不同种类的作用域是掌握这门语言的关键之一。作用域决定了变量和函数的可访问性&#xff08;即可见性和生命周期&#xff09;。与全局作用域相对应的是局部作用域&#xff0c;它限制了变量和函数只能在其定义的特定范围内被访问。本文将深入探讨…...

[特殊字符]Meilisearch:AI驱动的现代搜索引擎

前言 大家好&#xff0c;我是MAI麦造&#xff01; 上文介绍一了Manticore Search 这款轻量级的搜索引擎&#xff0c;这次又有了新的发现&#xff01;传送门&#xff1a; Elasticsearch太重&#xff1f;它的超轻量的替代品找到了&#xff01; 这是一个让我超级兴奋的AI搜索引…...

K8S Svc Port-forward 访问方式

在 Kubernetes 中&#xff0c;kubectl port-forward 是一种 本地与集群内资源&#xff08;Pod/Service&#xff09;建立临时网络隧道 的访问方式&#xff0c;无需暴露服务到公网&#xff0c;适合开发调试、临时访问等场景。以下是详细使用方法及注意事项&#xff1a; 1. 基础用…...

SD06_前后端分离项目部署流程(采用Nginx)

本文档详细描述了如何在Ubuntu 20.04服务器上从零开始部署Tlias前后端分离系统。Tlias系统由Spring Boot后端&#xff08;tlias-web-management&#xff09;和Vue前端&#xff08;vue-tlias-management&#xff09;组成。 目录 环境准备安装MySQL数据库部署后端项目部署前端项…...

计算机网络:家庭路由器WiFi信号的发射和手机终端接收信号原理?

WiFi路由器与手机之间的信号传输涉及多个技术层面的协作,以下是其工作原理的详细步骤: 一、数据封装与协议处理 应用层数据生成 用户操作(如浏览网页、视频播放)产生数据包,经TCP/IP协议栈逐层封装,添加IP地址(网络层)和MAC地址(数据链路层)。协议封装 数据包被封装…...

【Redis】string

文章目录 string 字符串常用命令设置和获取setgetmget & mset 计数操作incr & incrbydecr & decrbyincrbyfloat 字符串操作appendstrlengetrangesetrange string 字符串 关于 Redis 的字符串&#xff0c;有几点需要注意 Redis 所有的 key 的类型都是字符串类型va…...

vue3的响应式设计原理

Vue 3 的响应式设计是其核心特性之一&#xff0c;依赖于 Proxy 和 依赖收集机制&#xff0c;相比 Vue 2 的 Object.defineProperty&#xff0c;Vue 3 的响应式系统更加高效、灵活且易于维护。 以下是 Vue 3 响应式设计的核心原理&#xff1a; 一、核心机制概览 使用 Proxy 实现…...

学习黑客5 分钟深入浅出理解Linux Logs [特殊字符]

5 分钟深入浅出理解Linux Logs &#x1f4dd; 大家好&#xff01;今天我们将探索Linux系统中的日志机制——这是系统管理和安全分析的重要组成部分。在网络安全学习特别是TryHackMe平台上的挑战中&#xff0c;理解和分析日志是发现入侵痕迹、追踪攻击者行为和收集证据的关键技…...

【Docker系列】docker inspect查看容器部署位置

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

journalctl使用

journalctl 可以查看很多服务的日志&#xff0c;比如 docker&#xff0c;ollama 等。 1. 查看 xx 服务的最新日志&#xff08;实时滚动&#xff09; sudo journalctl -u docker -f -f 参数表示 跟随&#xff08;follow&#xff09;&#xff0c;会持续输出最新日志&#xff0…...

Satori:元动作 + 内建搜索机制,实现超级推理能力

Satori&#xff1a;元动作 内建搜索机制&#xff0c;实现超级推理能力 论文大纲一、背景&#xff1a;LLM 推理增强的三类方法1. 基于大规模监督微调&#xff08;SFT&#xff09;的推理增强2. 借助外部机制在推理时进行搜索 (RLHF / 多模型 / 工具)3. 现有局限性总结 二、Sator…...

基于语言模型的依存关系分句 和 主题变换检测(基于词频和句段得分)的 意思

&#x1f9e0; 一、基于语言模型的依存关系分句&#xff08;Dependency-based Segmentation&#xff09; ✅ 说人话&#xff1a; 用语言模型判断句子里的语法结构&#xff08;谁依赖谁&#xff09;&#xff0c;找到合理的“断点”&#xff0c;把太长的句子拆成语法上更自然的小…...

计算机体系结构一些笔记

1、异构计算&#xff1a;CPU也像人类社会一样存在专业分工。 异构计算&#xff08;Heterogeneous Computing&#xff09;是指不同类型的计算单元合作完 成计算任务。每个计算单元采用不同的架构&#xff0c;分别擅长处理某一种类型 的计算任务。整个计算任务分解为小的单位&…...

Go语言——goflow工作流使用

一、引入依赖 这个很坑&#xff0c;他不允许连接带密码的redis&#xff0c;只能使用不带密码的redis&#xff0c;要带密码的话得自己改一下源代码&#xff0c;无语 go get github.com/s8sg/goflow二、画出我们的工作流程 三、编写代码 package mainimport ("encoding/j…...

理性地倾听与表达:检索算法的语言学改进

论文标题 Rational Retrieval Acts: Leveraging Pragmatic Reasoning to Improve Sparse Retrieval 论文地址 https://arxiv.org/pdf/2505.03676 代码地址 https://github.com/arthur-75/Rational-Retrieval-Acts 作者背景 巴黎萨克雷大学&#xff0c;索邦大学&#xff…...

RV1126 ROS2环境交叉编译及部署(基于官方Docker)

RV1126 ROS2环境交叉编译及部署(基于官方Docker) 0 前言1 SDK源码更新1.1 启动Docker容器1.2 更新SDK源码1.3 SDK更新问题2 ROS2编译配置3 Buildroot rootfs编译ROS2的依赖包3.1 编译问题解决4 使用Docker交叉编译ROS24.1 准备Linux(Ubuntu) PC机的依赖环境4.1.1 Ubuntu PC机…...

每日脚本学习5.10 - XOR脚本

xor运算的简介 异或就是对于二进制的数据可以 进行同0异1 简单的演示 &#xff1a; 结果是 这个就是异或 异或的作用 1、比较两数是否相等 2、可以进行加密 加密就是需要key 明文 :0b010110 key : 0b1010001 这个时候就能进行加密 明文 ^ key密文 还有这个加密比…...