JAVA极简图书管理系统,初识springboot后端项目
前提条件:
具备基础的springboot 知识
Java基础
废话不多说!
创建项目



配置所需环境
将application.properties==>application.yml 配置以下环境
数据库连接MySQL
自己创建的数据库名称为book_test
server:port: 8080
spring:datasource:url: jdbc:mysql://localhost:3306/book_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermvc:hiddenmethod:filter:enabled: truemybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl#一直出现的问题:引入依赖包的问题
追加两个依赖使得可以使用mapper-locations

数据库准备
图书以及简单的用户信息
CREATE TABLE `book_info` (`id` INT(10) NOT NULL AUTO_INCREMENT,`book_name` VARCHAR(127) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',`author` VARCHAR(127) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',`count` INT(10) NULL DEFAULT NULL,`price` DECIMAL(7,2) NOT NULL,`publish` VARCHAR(256) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',`status` TINYINT(3) NULL DEFAULT '1' COMMENT '0-⽆效, 1-正常, 2-不允许借阅',`create_time` DATETIME NULL DEFAULT 'CURRENT_TIMESTAMP',`update_time` DATETIME NULL DEFAULT 'CURRENT_TIMESTAMP' ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
AUTO_INCREMENT=25
;
CREATE TABLE `user_info` (`id` INT(10) NOT NULL AUTO_INCREMENT,`user_name` VARCHAR(128) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',`password` VARCHAR(128) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',`delete_flag` TINYINT(3) NULL DEFAULT '0',`create_time` DATETIME NULL DEFAULT 'CURRENT_TIMESTAMP',`update_time` DATETIME NULL DEFAULT 'CURRENT_TIMESTAMP' ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `user_name_UNIQUE` (`user_name`) USING BTREE
)
COMMENT='用户表'
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
AUTO_INCREMENT=3
;


spring MVC 运行逻辑
Mapper ==> Service ==> Controller

mapper接口层代码:
@Insert("INSERT INTO book_info (book_name, author, count, price, publish, status, create_time, update_time) VALUES " +"(#{bookName}, #{author}, #{count}, #{price}, #{publish}, #{status}, #{createTime}, #{updateTime})")@Options(useGeneratedKeys = true, keyProperty = "id")int insertBook(BookInfo book);@Select("SELECT id, book_name AS bookName, author, count, price, publish, status, " +"CASE status WHEN 0 THEN '无效' WHEN 1 THEN '允许借阅' ELSE '不允许借阅' END AS statusCN, " +"create_time, update_time FROM book_info WHERE id = #{id}")@Results(id = "bookResultMap", value = {@Result(property = "id", column = "id"),@Result(property = "bookName", column = "bookName"),@Result(property = "author", column = "author"),@Result(property = "count", column = "count"),@Result(property = "price", column = "price"),@Result(property = "publish", column = "publish"),@Result(property = "status", column = "status"),@Result(property = "statusCN", column = "statusCN"),@Result(property = "createTime", column = "create_time"),@Result(property = "updateTime", column = "update_time")})BookInfo selectBookById(Integer id);@Update("UPDATE book_info SET book_name = #{bookName}, author = #{author}, count = #{count}, price = #{price}, " +"publish = #{publish}, status = #{status}, update_time = #{updateTime} WHERE id = #{id}")int updateBook(BookInfo book);@Delete("DELETE FROM book_info WHERE id = #{id}")int deleteBook(Integer id);@Select("SELECT * FROM book_info")List<BookInfo> selectAllBooks();List<BookInfo> mockData();
创建用户bookinfo
@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/login")public boolean login(String name, String password, HttpSession session){//账号或密码为空if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)){return false;}//模拟验证数据, 账号密码正确if("admin".equals(name) && "admin".equals(password)){session.setAttribute("userName",name);return true;}//账号密码错误return false;}
@Data
public class BookInfo {//图书IDprivate Integer id;//书名private String bookName;//作者private String author;//数量private Integer count;//定价private BigDecimal price;//出版社private String publish;//状态 0-⽆效 1-允许借阅 2-不允许借阅private Integer status;private String statusCN;//创建时间private Date createTime;//更新时间private Date updateTime;
}
service层面:
/*** 添加图书* @param book 图书信息* @return 操作结果,成功返回true,失败返回false*/boolean addBook(BookInfo book);/*** 根据ID查询图书* @param id 图书ID* @return 图书信息*/BookInfo getBookById(Integer id);/*** 更新图书信息* @param book 图书信息* @return 操作结果,成功返回true,失败返回false*/boolean updateBook(BookInfo book);/*** 删除图书* @param id 图书ID* @return 操作结果,成功返回true,失败返回false*/boolean deleteBook(Integer id);/*** 获取所有图书列表* @return 图书列表*/List<BookInfo> getAllBooks();
接口层的实现
private BookInfoMapper bookMapper;@Overridepublic boolean addBook(BookInfo book) {// 可以在这里添加业务逻辑校验,例如检查图书信息是否完整int rowsAffected = bookMapper.insertBook(book);return rowsAffected > 0;}@Overridepublic BookInfo getBookById(Integer id) {return bookMapper.selectBookById(id);}@Overridepublic boolean updateBook(BookInfo book) {// 业务逻辑校验,例如确保ID不为空且存在对应的图书记录int rowsAffected = bookMapper.updateBook(book);return rowsAffected > 0;}@Overridepublic boolean deleteBook(Integer id) {// 可以添加逻辑判断,比如检查图书是否已被借阅不能删除int rowsAffected = bookMapper.deleteBook(id);return rowsAffected > 0;}@Overridepublic List<BookInfo> getAllBooks() {return bookMapper.selectAllBooks();}
控制层面:
@Autowiredprivate BookService bookService;// 添加图书@PostMapping("/add")public ResponseEntity<ResponseMessage> addBook(@RequestBody BookInfo book) {
// boolean isAdded = bookService.addBook(book);
// if (isAdded) {
// return ResponseEntity.status(200).body(book);
// } else {
// return ResponseEntity.badRequest().build();
// }try {boolean isAdded = bookService.addBook(book);if (isAdded) {// 创建ResponseMessage实例,表示成功ResponseMessage response = new ResponseMessage(200, "图书添加成功", book);return ResponseEntity.ok(response); // 注意这里返回的是ResponseEntity<ResponseMessage>} else {// 创建ResponseMessage实例,表示失败ResponseMessage response = new ResponseMessage(400, "图书添加失败,请检查输入信息", null);return ResponseEntity.badRequest().body(response); // 同样返回ResponseEntity<ResponseMessage>}} catch (Exception e) {// 异常处理,返回错误信息ResponseMessage response = new ResponseMessage(500, "添加图书时发生系统错误: " + e.getMessage(), null);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);}}// 根据ID获取图书信息@GetMapping("/{id}")public ResponseEntity<BookInfo> getBookById(@PathVariable Integer id) {BookInfo book = bookService.getBookById(id);if (book != null) {return ResponseEntity.ok(book);} else {return ResponseEntity.notFound().build();}}// 更新图书信息@PutMapping("/{id}")public ResponseEntity<Void> updateBook(@PathVariable Integer id, @RequestBody BookInfo book) {book.setId(id); // 确保请求体中的ID与路径变量ID一致boolean isUpdated = bookService.updateBook(book);if (isUpdated) {return ResponseEntity.noContent().build();} else {return ResponseEntity.notFound().build();}}// 删除图书@DeleteMapping("/{id}")public ResponseEntity<Void> deleteBook(@PathVariable Integer id) {boolean isDeleted = bookService.deleteBook(id);if (isDeleted) {return ResponseEntity.noContent().build();} else {return ResponseEntity.notFound().build();}}// 获取所有图书列表@GetMappingpublic ResponseEntity<List<BookInfo>> getAllBooks() {List<BookInfo> books = bookService.getAllBooks();return ResponseEntity.ok(books);}
public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public ResponseMessage(int code, String message, Object data) {this.code = code;this.message = message;this.data = data;}private int code; // 状态码,200表示成功,非200表示各种错误private String message; // 描述信息private Object data; // 可选,成功时返回的数据或错误时的额外信息
后端结束
前台交互
增加图书:
<!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/add.css"></head><body><div class="container"><div class="form-inline"><h2 style="text-align: left; margin-left: 10px;"><svg xmlns="http://www.w3.org/2000/svg" width="40"fill="#17a2b8" class="bi bi-book-half" viewBox="0 0 16 16"><pathd="M8.5 2.687c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z" /></svg><span>添加图书</span></h2></div><form id="addBook"><div class="form-group"><label for="bookName">图书名称:</label><input type="text" class="form-control" placeholder="请输入图书名称" id="bookName" name="bookName"></div><div class="form-group"><label for="bookAuthor">图书作者</label><input type="text" class="form-control" placeholder="请输入图书作者" id="bookAuthor" name="author" /></div><div class="form-group"><label for="bookStock">图书库存</label><input type="text" class="form-control" placeholder="请输入图书库存" id="bookStock" name="count"/></div><div class="form-group"><label for="bookPrice">图书定价:</label><input type="number" class="form-control" placeholder="请输入价格" id="bookPrice" name="price"></div><div class="form-group"><label for="bookPublisher">出版社</label><input type="text" id="bookPublisher" class="form-control" placeholder="请输入图书出版社" name="publish" /></div><div class="form-group"><label for="bookStatus">图书状态</label><select class="custom-select" id="bookStatus" name="status"><option value="1" selected>可借阅</option><option value="2">不可借阅</option></select></div><div class="form-group" style="text-align: right"><button type="button" class="btn btn-info btn-lg" onclick="add()">确定</button><button type="button" class="btn btn-secondary btn-lg" onclick="history.back()">返回</button></div></form></div><script type="text/javascript" src="js/jquery.min.js"></script><script>function add() {// 收集表单数据const formData = {bookName: $("#bookName").val(),author: $("#bookAuthor").val(),count: $("#bookStock").val(),price: $("#bookPrice").val(),publish: $("#bookPublisher").val(),status: $("#bookStatus").val()};// 使用Ajax发送数据到后端$.ajax({type: "POST",url: "/book/add", //请替换为您的后端接口地址contentType: "application/json; charset=utf-8",data: JSON.stringify(formData),success: function(response) {if(response.code === 200 || response.code === 201) { // 假设200或201都表示成功// alert(response.code);alert("添加成功");location.href = "book_list.html"; // 添加成功后跳转到列表页} else {alert("添加失败:" + response.message);}},error: function(xhr, status, error) {alert("添加图书时发生错误: " + error);}});}</script>
</body></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 class="table"><thead><tr><th><label for="selectAllBooks"></label><input type="checkbox" id="selectAllBooks"></th><th>ID</th><th>书名</th><th>作者</th><th>数量</th><th>定价</th><th>出版社</th><th>状态</th><th>操作</th></tr></thead><tbody></tbody></table><div class="demo"><ul id="pageContainer" class="pagination justify-content-center"></ul></div><script>$(document).ready(function() {getBookList();$("#selectAllBooks").click(function() {$("input[name='selectBook']").prop('checked', this.checked);});});function getBookList() {$.ajax({type: "get",url: "/book"+location.search,success: function (result) {console.log(result);if (result != null) {let finalHtml = "";for (const book of result) {finalHtml += '<tr>';finalHtml += '<td><input type="checkbox" name="selectBook" value="' + book.id + '"></td>'; // 修正了value属性的遗漏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 + '" class="btn btn-sm btn-primary">编辑</a>'; // 修正了链接的闭合finalHtml += '<button class="btn btn-sm btn-danger" onclick="deleteBook(' + book.id + ')">删除</button>';finalHtml += '</div></td>';finalHtml += '</tr>';}$("tbody").html(finalHtml);}}});}function deleteBook(id) {const isDelete = confirm("确认删除?");if (isDelete) {$.ajax({type: "DELETE",url: "/book/" + id,success: function() {alert("删除成功");// 刷新页面以反映删除后的数据变化getBookList();location.reload();},error: function(xhr, status, error) {if (xhr.status === 404) {alert("图书不存在");} else {alert("删除失败: " + error);}}});}}function batchDelete() {const isDelete = confirm("确认批量删除?");if (isDelete) {//获取复选框的idconst ids = [];$("input:checkbox[name='selectBook']:checked").each(function () {ids.push($(this).val());});console.log(ids);alert("批量删除成功");}}</script>
</div>
</body></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/add.css">
</head><body><div class="container"><div class="form-inline"><h2 style="text-align: left; margin-left: 10px;"><svg xmlns="http://www.w3.org/2000/svg" width="40"fill="#17a2b8" class="bi bi-book-half" viewBox="0 0 16 16"><pathd="M8.5 2.687c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z" /></svg><span>修改图书</span></h2></div><form id="updateBook"><input type="hidden" class="form-control" id="bookId" name="id"><div class="form-group"><label for="bookName">图书名称:</label><input type="text" class="form-control" id="bookName" name="bookName"></div><div class="form-group"><label for="bookAuthor">图书作者</label><input type="text" class="form-control" id="bookAuthor" name="author"/></div><div class="form-group"><label for="bookStock">图书库存</label><input type="text" class="form-control" id="bookStock" name="count"/></div><div class="form-group"><label for="bookPrice">图书定价:</label><input type="number" class="form-control" id="bookPrice" name="price"></div><div class="form-group"><label for="bookPublisher">出版社</label><input type="text" id="bookPublisher" class="form-control" name="publish"/></div><div class="form-group"><label for="bookStatus">图书状态</label><select class="custom-select" id="bookStatus" name="status"><option value="1" selected>可借阅</option><option value="2">不可借阅</option></select></div><div class="form-group" style="text-align: right"><button type="button" class="btn btn-info btn-lg" onclick="update()">确定</button><button type="button" class="btn btn-secondary btn-lg" onclick="history.back()">返回</button></div></form></div><script type="text/javascript" src="js/jquery.min.js"></script><!-- HTML 表单保持不变 --><script>function update() {// 收集表单数据const formData = {id: location.search.split("=")[1], // 确保隐藏字段包含图书IDbookName: $("#bookName").val(),author: $("#bookAuthor").val(),count: $("#bookStock").val(),price: $("#bookPrice").val(),publish: $("#bookPublisher").val(),status: $("#bookStatus").val()};// 对id进行Base64编码// 使用Ajax发送PUT请求到Spring Boot后端更新图书,URL中包含Base64编码的id// 构建正确的URL,使用模板字符串动态插入IDconsole.log("--------------"+formData)const urls = `/book/${formData.id}`;// 使用Ajax发送PUT请求到Spring Boot后端更新图书$.ajax({type: "PUT",url: urls, // 使用上面构建的正确URLcontentType: "application/json; charset=utf-8",data: JSON.stringify(formData),success: function(response, textStatus, jqXHR) {if(jqXHR.status === 204) {alert("更新成功");location.href = "book_list.html";} else if(response.status === 'SUCCESS') {alert("更新成功");location.href = "book_list.html";} else {alert("更新失败:" + response.message);}},error: function(xhr, status, error) {alert("更新图书时发生错误: " + xhr.responseText || error);}});}</script>
</body></html>
用户登录页面:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/bootstrap.min.css"><link rel="stylesheet" href="css/login.css"><script type="text/javascript" src="js/jquery.min.js"></script>
</head><body><div class="container-login"><div class="container-pic"><img src="pic/computer.png" width="713" alt=""></div><div class="login-dialog"><h3>登陆</h3><div class="row"><span>用户名</span><label for="userName"></label><input type="text" name="userName" id="userName" class="form-control"></div><div class="row"><span>密码</span><label for="password"></label><input type="password" name="password" id="password" class="form-control"></div><div class="row"><button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button></div></div></div><script src="js/jquery.min.js"></script><script>function login() {$.ajax({type: "post",url: "/user/login",data: {name: $("#userName").val(),password: $("#password").val()},success: function (result) {if (result) {location.href = "book_list.html";} else {alert("账号或密码不正确!");}}});}</script>
</body></html>
总结:
src/main/java/bao/book_again目录下的BookAgainApplication.java是项目的启动类,它继承了Spring Boot的SpringBootApplication,并使用@SpringBootApplication注解开启自动配置和扫描。
Controller目录下有多个控制器类,如BasicController.java和PathVariableController.java,它们使用Spring MVC的@RestController或@Controller注解,处理来自客户端的HTTP请求,并返回相应的响应。
Domain目录下有领域模型类,如User.java和BookInfo.java,它们代表了应用中的实体对象。
Exception目录下有异常处理类,如ResponseMessage.java,可能是用于封装错误信息和响应状态的类。
Mapper目录下有MyBatis的相关接口,如BookService.java,它们定义了数据库操作的接口。
Service目录下有服务层实现,如BookServiceImpl.java,实现了业务逻辑。
resources/static目录下有静态资源,如HTML文件和图片。
application.yml是项目的配置文件,用于配置Spring Boot应用的各种属性。
test目录下可能有单元测试或集成测试代码。这个项目使用了Spring Boot和Spring MVC,结合MyBatis作为持久层框架,实现了基本的CRUD操作。用户界面使用HTML模板,通过RESTful API与后端交互。整体来看,这是一个典型的MVC架构的Web应用,其中
Controller负责处理HTTP请求,Service层处理业务逻辑,Mapper层处理数据库操作,Domain层定义了领域模型,Exception层处理异常,static目录下存放了前端资源
相关文章:
JAVA极简图书管理系统,初识springboot后端项目
前提条件: 具备基础的springboot 知识 Java基础 废话不多说! 创建项目 配置所需环境 将application.properties>application.yml 配置以下环境 数据库连接MySQL 自己创建的数据库名称为book_test server:port: 8080 spring:datasource:url:…...
MySQL 重新初始化实例
1、关闭mysql服务 service mysqld stop 2、清理datadir(本例中指定的是/var/lib/mysql)指定的目录下的文件,将该目录下的所有文件删除或移动至其他位置 cd /var/lib/mysql mv * /opt/mysql_back/ 3、初始化实例 /usr/local/mysql/bin/mysqld --initialize --u…...
VCS编译bug汇总
‘typedef’ is not expected to be used in this contex 注册前少了分号。 Scope resolution error resolution : 声明指针时 不能与类名同名,即 不能声明为adapter. cannot find member "type_id" 忘记注册了 拼接运算符使用 关键要加上1b࿰…...
【2024LLM应用-数据预处理】之如何从PDF,PPT等非结构化数据提取有效信息(结构化数据JSON)?
🥰大家知道吗,之前在给AI大模型"喂数据"的时候,我们往往需要把非结构化数据(比如PDF、PPT、Excel等)自己手动转成结构化的格式,这可真是太累人儿了。🥵 幸好现在有了Unstructured这个神级库,它内置的数据提取函数可以帮我们快速高效地完成这个…...
冯雷老师:618大退货事件分析
近日冯雷老师受邀为某头部电商36名高管进行培训,其中聊到了今年618退货潮的问题。以下内容整理自冯雷老师的部分授课内容。 一、引言 随着电子商务的蓬勃发展,每年的618大促已成为消费者和商家共同关注的焦点。然而,在销售额不断攀升的同时…...
JAVA基础教程DAY0-基础知识
JAVA语言的特点 简单性、面向对象、安全性、跨平台性、支持多线程、分布性 面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它通过将数据和操作这些数据的方法封装在一起,以创建对象的形式来组织代…...
鸿蒙开发Ability Kit(程序访问控制):【安全控件概述】
安全控件概述 安全控件是系统提供的一组系统实现的ArkUI组件,应用集成这类组件就可以实现在用户点击后自动授权,而无需弹窗授权。它们可以作为一种“特殊的按钮”融入应用页面,实现用户点击即许可的设计思路。 相较于动态申请权限的方式&am…...
【信息系统项目管理师】18年~23年案例概念型知识
文章目录 18上18下19上19下20上20下21上21下22年上22年下23年上 18上 请简述 ISO 9000 质量管理的原则 领导作用、 过程方法、 管理的系统方法、 与供方互利的关系、 基于事实的决策方法、 持续改进、 全员参与、 以顾客为关注焦点 概念 国家标准(GB/T 1 9000 2008)对质量的定…...
什么是字符串常量池?如何利用它来节省内存?
字符串常量池是Java中一个非常重要的概念,尤其对于理解内存管理和性能优化至关重要。想象一下,你正在管理一家大型图书馆,每天都有无数读者来借阅书籍。 如果每本书每次借阅都需要重新印刷一本,那么图书馆很快就会陷入混乱&#…...
Selenium自动化测试20条常见异常+处理方案
常见的Selenium异常 以下是所有Selenium WebDriver代码中可能发生的一些常见Selenium异常。 1、ElementClickInterceptedException 由于以某种方式隐藏了接收到click命令的元素,因此无法正确执行Element Click命令。 2、ElementNotInteractableException 即使目…...
verilog将信号和常数拼接起来
正确的拼接 1 s_axis_data_tdata {32b0000_0000_0000_0000_0000_0000_0000_0000,32b0011_1111_1000_0000_0000_0000_0000_0000}; 2 注意,信号的两部分都要用{}花括号括起来 s_axis_data_tdata {{32{1b1}},{32b0100_0000_0000_0000_0000_0000_0000_0000}}; 3…...
OpenSSH远程代码执行漏洞 (CVE-2024-6387)
1. 前言 OpenSSH是一套基于安全外壳(SSH)协议的安全网络实用程序,它提供强大的加密功能以确保隐私和安全的文件传输,使其成为远程服务器管理和安全数据通信的必备工具。 OpenSSH 自 1995 年问世近 20 年来,首次出现了…...
高薪程序员必修课-java并发编程的bug源头
前言 Java并发编程虽然强大,但也容易引发复杂的bug。并发编程的bug主要源自以下几个方面:竞态条件、死锁、内存可见性问题和线程饥饿。了解这些bug的源头及其原理,可以帮助开发者避免和解决这些问题。以下是详细的讲解和相应的示例。 1. 竞态…...
c++:#include 某文件.h底层如何寻找其.cpp实现
在C中,当你编写了一个头文件(如MyLibrary.h)和对应的实现文件(如MyLibrary.cpp)时,其他源文件(如main.cpp)只需要包含头文件(#include "MyLibrary.h"ÿ…...
uniapp中如何进行微信小程序的分包
思路:在uniapp中对微信小程序进行分包,和原生微信小程序进行分包的操作基本上没区别,主要就是在pages.json中进行配置。 如图,我新增了一个包diver-page 此时需要在pages.json中的subPackages数组中新增一项 root代表这个包的根…...
win10下安装PLSQL14连接Oracle数据库
问题背景 在使用Oracle开发过程中,经常会使用工具来连接数据库,方便查询、处理数据。其中有很多工具可以使用,比如dbeaver、plsql等。本文主要介绍在win10环境下,plsql14的安装步骤以及安装过程中遇到的一些问题。 安装步骤及问题…...
高考失利咨询复读,银河补习班客服开挂回复
补习班的客服在高考成绩出来后,需要用专业的知识和足够的耐心来回复各种咨询,聊天宝快捷回复软件,帮助客服开挂回复。 前言 高考成绩出来,几家欢喜几家愁,对于高考失利的学生和家长,找一个靠谱的复读补…...
java 代码块
Java中的代码块主要有三种类型:普通代码块、静态代码块、构造代码块。它们的用途和执行时机各不相同。 普通代码块:在方法内部定义,使用一对大括号{}包围的代码片段。它的作用域限定在大括号内,每当程序执行到该代码块时就会执行其…...
vue中避免多次请求字典接口
vuex缓存所有字典项 背景vuex管理所有字典项调用字典接口处理字典项数据的filter页面中使用字典 背景 每次用到字典都需要通过对应的字典type调用一次字典接口,当一个页面用到字典项很多时,接口请求炒鸡多,会导致接口响应超时。 本篇文章改为…...
Snappy使用
Snappy使用 Snappy是谷歌开源的压缩和解压的开发包,目标在于实现高速的压缩而不是最大的压缩 项目地址:GitHub - google/snappy:快速压缩器/解压缩器 Cmake版本升级 该项目需要比较新的cmake,CMake 3.16.3 or higher is requi…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
