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

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>

总结:

  1. src/main/java/bao/book_again 目录下的 BookAgainApplication.java 是项目的启动类,它继承了Spring Boot的SpringBootApplication,并使用@SpringBootApplication注解开启自动配置和扫描。

  2. Controller 目录下有多个控制器类,如 BasicController.javaPathVariableController.java,它们使用Spring MVC的@RestController@Controller注解,处理来自客户端的HTTP请求,并返回相应的响应。

  3. Domain 目录下有领域模型类,如 User.javaBookInfo.java,它们代表了应用中的实体对象。

  4. Exception 目录下有异常处理类,如 ResponseMessage.java,可能是用于封装错误信息和响应状态的类。

  5. Mapper 目录下有MyBatis的相关接口,如 BookService.java,它们定义了数据库操作的接口。

  6. Service 目录下有服务层实现,如 BookServiceImpl.java,实现了业务逻辑。

  7. resources/static 目录下有静态资源,如HTML文件和图片。

  8. application.yml 是项目的配置文件,用于配置Spring Boot应用的各种属性。

  9. test 目录下可能有单元测试或集成测试代码。

这个项目使用了Spring Boot和Spring MVC,结合MyBatis作为持久层框架,实现了基本的CRUD操作。用户界面使用HTML模板,通过RESTful API与后端交互。整体来看,这是一个典型的MVC架构的Web应用,其中Controller负责处理HTTP请求,Service层处理业务逻辑,Mapper层处理数据库操作,Domain层定义了领域模型,Exception层处理异常,static目录下存放了前端资源

相关文章:

JAVA极简图书管理系统,初识springboot后端项目

前提条件&#xff1a; 具备基础的springboot 知识 Java基础 废话不多说&#xff01; 创建项目 配置所需环境 将application.properties>application.yml 配置以下环境 数据库连接MySQL 自己创建的数据库名称为book_test server:port: 8080 spring:datasource:url:…...

MySQL 重新初始化实例

1、关闭mysql服务 service mysqld stop 2、清理datadir(本例中指定的是/var/lib/mysql)指定的目录下的文件&#xff0c;将该目录下的所有文件删除或移动至其他位置 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 : 声明指针时 不能与类名同名&#xff0c;即 不能声明为adapter. cannot find member "type_id" 忘记注册了 拼接运算符使用 关键要加上1b&#xff0…...

【2024LLM应用-数据预处理】之如何从PDF,PPT等非结构化数据提取有效信息(结构化数据JSON)?

&#x1f970;大家知道吗,之前在给AI大模型"喂数据"的时候,我们往往需要把非结构化数据(比如PDF、PPT、Excel等)自己手动转成结构化的格式,这可真是太累人儿了。&#x1f975; 幸好现在有了Unstructured这个神级库,它内置的数据提取函数可以帮我们快速高效地完成这个…...

冯雷老师:618大退货事件分析

近日冯雷老师受邀为某头部电商36名高管进行培训&#xff0c;其中聊到了今年618退货潮的问题。以下内容整理自冯雷老师的部分授课内容。 一、引言 随着电子商务的蓬勃发展&#xff0c;每年的618大促已成为消费者和商家共同关注的焦点。然而&#xff0c;在销售额不断攀升的同时…...

JAVA基础教程DAY0-基础知识

JAVA语言的特点 简单性、面向对象、安全性、跨平台性、支持多线程、分布性 面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种编程范式&#xff0c;它通过将数据和操作这些数据的方法封装在一起&#xff0c;以创建对象的形式来组织代…...

鸿蒙开发Ability Kit(程序访问控制):【安全控件概述】

安全控件概述 安全控件是系统提供的一组系统实现的ArkUI组件&#xff0c;应用集成这类组件就可以实现在用户点击后自动授权&#xff0c;而无需弹窗授权。它们可以作为一种“特殊的按钮”融入应用页面&#xff0c;实现用户点击即许可的设计思路。 相较于动态申请权限的方式&am…...

【信息系统项目管理师】18年~23年案例概念型知识

文章目录 18上18下19上19下20上20下21上21下22年上22年下23年上 18上 请简述 ISO 9000 质量管理的原则 领导作用、 过程方法、 管理的系统方法、 与供方互利的关系、 基于事实的决策方法、 持续改进、 全员参与、 以顾客为关注焦点 概念 国家标准(GB/T 1 9000 2008)对质量的定…...

什么是字符串常量池?如何利用它来节省内存?

字符串常量池是Java中一个非常重要的概念&#xff0c;尤其对于理解内存管理和性能优化至关重要。想象一下&#xff0c;你正在管理一家大型图书馆&#xff0c;每天都有无数读者来借阅书籍。 如果每本书每次借阅都需要重新印刷一本&#xff0c;那么图书馆很快就会陷入混乱&#…...

Selenium自动化测试20条常见异常+处理方案

常见的Selenium异常 以下是所有Selenium WebDriver代码中可能发生的一些常见Selenium异常。 1、ElementClickInterceptedException 由于以某种方式隐藏了接收到click命令的元素&#xff0c;因此无法正确执行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 注意&#xff0c;信号的两部分都要用{}花括号括起来 s_axis_data_tdata {{32{1b1}},{32b0100_0000_0000_0000_0000_0000_0000_0000}}; 3…...

OpenSSH远程代码执行漏洞 (CVE-2024-6387)

1. 前言 OpenSSH是一套基于安全外壳&#xff08;SSH&#xff09;协议的安全网络实用程序&#xff0c;它提供强大的加密功能以确保隐私和安全的文件传输&#xff0c;使其成为远程服务器管理和安全数据通信的必备工具。 OpenSSH 自 1995 年问世近 20 年来&#xff0c;首次出现了…...

高薪程序员必修课-java并发编程的bug源头

前言 Java并发编程虽然强大&#xff0c;但也容易引发复杂的bug。并发编程的bug主要源自以下几个方面&#xff1a;竞态条件、死锁、内存可见性问题和线程饥饿。了解这些bug的源头及其原理&#xff0c;可以帮助开发者避免和解决这些问题。以下是详细的讲解和相应的示例。 1. 竞态…...

c++:#include 某文件.h底层如何寻找其.cpp实现

在C中&#xff0c;当你编写了一个头文件&#xff08;如MyLibrary.h&#xff09;和对应的实现文件&#xff08;如MyLibrary.cpp&#xff09;时&#xff0c;其他源文件&#xff08;如main.cpp&#xff09;只需要包含头文件&#xff08;#include "MyLibrary.h"&#xff…...

uniapp中如何进行微信小程序的分包

思路&#xff1a;在uniapp中对微信小程序进行分包&#xff0c;和原生微信小程序进行分包的操作基本上没区别&#xff0c;主要就是在pages.json中进行配置。 如图&#xff0c;我新增了一个包diver-page 此时需要在pages.json中的subPackages数组中新增一项 root代表这个包的根…...

win10下安装PLSQL14连接Oracle数据库

问题背景 在使用Oracle开发过程中&#xff0c;经常会使用工具来连接数据库&#xff0c;方便查询、处理数据。其中有很多工具可以使用&#xff0c;比如dbeaver、plsql等。本文主要介绍在win10环境下&#xff0c;plsql14的安装步骤以及安装过程中遇到的一些问题。 安装步骤及问题…...

高考失利咨询复读,银河补习班客服开挂回复

补习班的客服在高考成绩出来后&#xff0c;需要用专业的知识和足够的耐心来回复各种咨询&#xff0c;聊天宝快捷回复软件&#xff0c;帮助客服开挂回复。 ​ 前言 高考成绩出来&#xff0c;几家欢喜几家愁&#xff0c;对于高考失利的学生和家长&#xff0c;找一个靠谱的复读补…...

java 代码块

Java中的代码块主要有三种类型&#xff1a;普通代码块、静态代码块、构造代码块。它们的用途和执行时机各不相同。 普通代码块&#xff1a;在方法内部定义&#xff0c;使用一对大括号{}包围的代码片段。它的作用域限定在大括号内&#xff0c;每当程序执行到该代码块时就会执行其…...

vue中避免多次请求字典接口

vuex缓存所有字典项 背景vuex管理所有字典项调用字典接口处理字典项数据的filter页面中使用字典 背景 每次用到字典都需要通过对应的字典type调用一次字典接口&#xff0c;当一个页面用到字典项很多时&#xff0c;接口请求炒鸡多&#xff0c;会导致接口响应超时。 本篇文章改为…...

Snappy使用

Snappy使用 Snappy是谷歌开源的压缩和解压的开发包&#xff0c;目标在于实现高速的压缩而不是最大的压缩 项目地址&#xff1a;GitHub - google/snappy&#xff1a;快速压缩器/解压缩器 Cmake版本升级 该项目需要比较新的cmake&#xff0c;CMake 3.16.3 or higher is requi…...

跨越重洋:在Heroku上配置Pip镜像源的终极指南

&#x1f310; 跨越重洋&#xff1a;在Heroku上配置Pip镜像源的终极指南 Heroku是一个支持多种编程语言的云平台即服务&#xff08;PaaS&#xff09;&#xff0c;它允许开发者部署和管理应用程序。然而&#xff0c;由于Heroku的服务器位于海外&#xff0c;直接使用Python的包管…...

SpringBoot + 虚拟线程,性能炸裂!

一、什么是虚拟线程 虚拟线程是Java19开始增加的一个特性&#xff0c;和Golang的携程类似&#xff0c;一个其它语言早就提供的、且如此实用且好用的功能&#xff0c;作为一个Java开发者&#xff0c;早就已经望眼欲穿了。 二、虚拟线程和普通线程的区别 “虚拟”线程&#xf…...

Java Character类

Character是char的包装类 转义序列 Character类的方法...

Python中的爬虫实战:猫眼电影爬虫

随着互联网技术的快速发展&#xff0c;网络上的信息量越来越庞大。猫眼电影作为国内领先的电影数据平台&#xff0c;为用户提供了全面的电影信息服务。本文将介绍如何利用python编写简单的猫眼电影爬虫&#xff0c;获取电影相关数据。 爬虫概述 爬虫&#xff0c;即网络爬虫&a…...

WAIC2024 | 华院计算邀您共赴2024年世界人工智能大会,见证未来科技革新

在智能时代的浪潮汹涌澎湃之际&#xff0c;算法已成为推动社会进步的核心力量。作为中国认知智能技术的领军企业&#xff0c;华院计算在人工智能的广阔天地中&#xff0c;不断探索、创新&#xff0c;致力于将算法的潜力发挥到极致。在过去的时日里&#xff0c;华院计算不断探索…...

数据库原理之数据库基本概念

目录 前言 基本概念 数据库完整性 前言 今天我们来看看数据库的基本概念&#xff0c;帮助大家对数据库有一点点最基本的了解 基本概念 4个基本概念 数据data&#xff1a;描述事物的符号&#xff0c;数据库中存储的基本对象。 数据库Database&#xff1a;长期存储在计算机…...

vue2项目的打包以及部署

打包 当我们写好vue2的项目后&#xff0c;可以通过npm build来对项目进行打包 npm build 打包完成后我们可以看到在当面目录下生成了dis目录,src下的文件都会被打包进这个目录里&#xff0c;当然打包后的文件我们不能直接在浏览器打开&#xff0c;需要进行部署 部署 1.新建一个…...

Java的全局异常处理代码

第一步&#xff1a;先写一个异常管理类: package com.example.firefighting.exceptions;import com.example.firefighting.utils.Result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerA…...

Hi3861 OpenHarmony嵌入式应用入门--LiteOS semaphore作为锁

CMSIS 2.0 接口中的 Semaphore&#xff08;信号量&#xff09;是用于嵌入式系统中多线程或中断服务例程&#xff08;ISR&#xff09;之间同步和共享资源保护的重要机制。Semaphore 是一种用于控制对多个共享资源访问的同步机制。它可以被看作是一个计数器&#xff0c;用于跟踪可…...

注意!年龄越大,社交圈子越窄?其实这是老人的理性选择!数学家告诉你:何时该跳槽,何时该坚守!你必须知道的三个智慧:让你的人生更加精彩!

我们到底应该在什么情况下探索新事物&#xff0c;什么情况下专注于已有的东西呢&#xff1f;本质上来说&#xff0c;这个问题就是在询问&#xff0c;你究竟应该耗费精力去探索新的信息&#xff0c;还是专注从既有的信息中获取收获&#xff1f; 有人采访了临终的老人&#xff0c…...

[SwiftUI 开发] 嵌套的ObservedObject中的更改不会更新UI

1. 发生问题的demo 业务逻辑代码 class Address: ObservableObject {Published var street "123 Apple Street"Published var city "Cupertino" }class User: ObservableObject {Published var name "Tim Cook"Published var address Addr…...

全面了解机器学习

目录 一、基本认识 1. 介绍 2. 机器学习位置 二、机器学习的类型 1. 监督学习 2. 无监督学习 3. 强化学习 三、机器学习术语 1. 训练样本 2. 训练 3. 特征 4. 目标 5. 损失函数 四、机器学习流程 五、机器学习算法 1. 分类算法 2. 聚类算法 3. 关联分析 4. …...

作为图形渲染API,OpenGL和Direct3D的全方位对比。

当你在网页看到很多美轮美奂的图形效果&#xff0c;3D交互效果&#xff0c;你知道是如何实现的吗&#xff1f;当然是借助图形渲染API了&#xff0c;说起这个不就不得说两大阵营&#xff0c;OpenGL和Direct3D&#xff0c;贝格前端工场在本文对二者做个详细对比。 一、什么是图形…...

安装Rabbitmq遇到的坑

&#xff01;&#xff01;&#xff01;一定要对号版本号 不同的虚拟机unbontu、cetenos和不同的erlang和不同的rabbitmq之间要对应下载对应版本 下面给出我的版本centos7erlangrabbitmq 分割线 安装好后&#xff0c;如果在虚拟机的服务器上可以打开&#xff0c;在本地浏览器…...

React+TS 从零开始教程(4):useEffect

上一节传送门&#xff1a;ReactTS 从零开始教程&#xff08;3&#xff09;&#xff1a;useState 源码链接&#xff1a;https://pan.quark.cn/s/c6fbc31dcb02 上一节&#xff0c;我们已经学会了React的第一个Hook&#xff1a;useState。 这一节&#xff0c;我们要学习的是另一…...

网络安全学习路线图(2024版详解)

近期&#xff0c;大家在网上对于网络安全讨论比较多&#xff0c;想要学习的人也不少&#xff0c;但是需要学习哪些内容&#xff0c;按照什么顺序去学习呢&#xff1f;其实我们已经出国多版本的网络安全学习路线图&#xff0c;一直以来效果也比较不错&#xff0c;本次我们针对市…...

你了解人工智能吗?

前言 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是计算机科学的一个重要分支&#xff0c;致力于开发能够执行通常需要人类智能的任务的系统。本文将从历史发展、关键技术、应用领域以及未来挑战等方面&#xff0c;深入探讨人工智能的相关内容。 …...

如何使用Vue.js实现动态文档生成与下载功能

在现代Web应用开发中&#xff0c;用户往往需要在浏览器端完成复杂的操作&#xff0c;如生成和下载特定格式的文档&#xff0c;而无需服务器直接干预。本文将以一个Vue.js应用程序为例&#xff0c;详细介绍如何利用axios&#xff08;或自定义请求模块&#xff09;结合FileReader…...

web基础及http协议

一、WEB&#xff1a;就是我们所说的页面&#xff0c;点开的每个页面都是web。&#xff08;全球广域网、万维网&#xff09; 分布式图形信息系统&#xff1a;同一个服务&#xff0c;但是部署在不同的机器上且提供的服务和内容全部一致&#xff0c;集群就是建立在分布式的基础上。…...

【vuejs】vue-router 之 addRoute 动态路由的应用总结

1. Vue Router 概述 Vue Router 是 Vue.js 官方的路由管理器&#xff0c;用于构建单页面应用。它与 Vue.js 深度集成&#xff0c;让开发者能够轻松地构建具有复杂用户界面的单页面应用。Vue Router 允许你定义不同的路由&#xff0c;并通过 router-view 组件在应用中显示匹配的…...

LeetCode 30. 串联所有单词的子串

LeetCode 30. 串联所有单词的子串 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words [“ab”,“cd”,“ef”]&#xff0c; 那么 “abcd…...

python本学期所有代码!

第一单元 ----------------------------------------------------------------------- #圆面积的计算 radius 25 area 3.1415 * radius * radius print(area) print("{:.2f}".format(area)) --------------------------------------------------------------------…...

武汉星起航:无锡跨境电商加速“出海”,物流升级助品牌全球布局

随着全球化的不断深入&#xff0c;跨境电商作为数字外贸的新业态&#xff0c;正逐渐成为无锡企业拓展海外市场的重要渠道。武汉星起航关注到&#xff0c;近年来&#xff0c;无锡市通过积极推进国际物流枢纽建设&#xff0c;完善海外仓布局&#xff0c;以及各特色产业带的积极参…...

Python+Pytest+Allure+Yaml+Pymysql+Jenkins+GitLab接口自动化测试框架详解

PythonPytestAllureYaml接口自动化测试框架详解 编撰人&#xff1a;CesareCheung 更新时间&#xff1a;2024.06.20 一、技术栈 PythonPytestAllureYamlJenkinsGitLab 版本要求&#xff1a;Python3.7.0,Pytest7.4.4,Allure2.18.1,PyYaml6.0 二、环境配置 安装python3.7&…...

stm32-hal库(5)--usart串口通信三种模式(主从通信)(关于通信失败和串口不断发送数据问题的解决)

问题&#xff1a; 最近发现&#xff0c;stm32cubemx最新版本f1系列的hal库&#xff08;1.85版本&#xff09;生成的hal库&#xff0c;其中stm32f1xx_hal_uart.c的库文件中&#xff0c;其串口发送接收存在一些问题&#xff1a; 1.没有使用 __HAL_LOCK 和 __HAL_UNLOCK 宏&…...

一文学会LVS:概念、架构、原理、搭建过程、常用命令及实战案例

引言 随着互联网技术的飞速发展&#xff0c;服务器负载均衡技术变得越来越重要。LVS&#xff08;Linux Virtual Server&#xff09;作为一种高效的负载均衡解决方案&#xff0c;广泛应用于各大企业的生产环境中。本文将深入探讨LVS的概念、架构、工作原理&#xff0c;详细讲解其…...

[Go 微服务] Kratos 使用的简单总结

文章目录 1.Kratos 简介2.传输协议3.日志4.错误处理5.配置管理6.wire 1.Kratos 简介 Kratos并不绑定于特定的基础设施&#xff0c;不限定于某种注册中心&#xff0c;或数据库ORM等&#xff0c;所以您可以十分轻松地将任意库集成进项目里&#xff0c;与Kratos共同运作。 API -&…...

【unity实战】使用旧输入系统Input Manager 写一个 2D 平台游戏玩家控制器——包括移动、跳跃、滑墙、蹬墙跳

最终效果 文章目录 最终效果素材下载人物环境 简单绘制环境角色移动跳跃视差和摄像机跟随效果奔跑动画切换跳跃动画&#xff0c;跳跃次数限制角色添加2d物理材质&#xff0c;防止角色粘在墙上如果角色移动时背景出现黑线条方法一方法二 墙壁滑行实现角色滑墙不可以通过移动离开…...

【实战】EasyExcel实现百万级数据导入导出

文章目录 前言技术积累实战演示实现思路模拟代码测试结果 前言 最近接到一个百万级excel数据导入导出的需求&#xff0c;大概就是我们在进行公众号API群发的时候&#xff0c;需要支持500w以上的openid进行群发&#xff0c;并且可以提供发送openid数据的导出功能。可能有的同学…...

Graalvm配置文件与Feature和Substitute机制介绍

GraalVM介绍 GraalVM提前将Java应用程序编译成独立与机器码二进制文件&#xff08;可执行文件、动态库文件&#xff09;,如windows系统中的exe文件和dll文件。与在Java虚拟机&#xff08;JVM&#xff09;上运行的应用程序相比&#xff0c;这些二进制文件更小&#xff0c;启动速…...

逻辑图框架图等结构图类图的高效制作方式不妨进来看看

**逻辑图框架图等结构图类图的高效制作方式不妨进来看看** 基于我们每天都在处理大量的数据和信息。为了更清晰地理解和传达这些信息&#xff0c;结构图、逻辑图和框架图等可视化工具变得越来越重要。然而&#xff0c;如何高效地制作这些图表并确保其准确性和易读性呢&#xf…...

深度学习与浅层学习:技术变革下的竞争态势

深度学习与浅层学习&#xff1a;技术变革下的竞争态势 在过去十年中&#xff0c;深度学习的崛起对整个人工智能领域产生了巨大影响&#xff0c;几乎在各种任务中显示出超越传统浅层学习方法的性能。这种变化不仅推动了技术的进步&#xff0c;还对硬件市场&#xff0c;尤其是显…...

Linux系统安全加固:无需WAF也能有效防御黑客攻击

Web应用防火墙&#xff08;WAF&#xff09;是现代网络安全架构中的重要组成部分&#xff0c;用于保护Web应用程序免受各种攻击。然而&#xff0c;对于基于Linux的服务器&#xff0c;即使没有部署WAF&#xff0c;通过合理的配置和策略&#xff0c;依然能够构建起坚固的防线。本文…...

数据库设计(实战项目)-1个手机号多用户身份

一. 背景&#xff1a; 该需求是一个互联网医院的预约单场景&#xff0c;护士在小程序上申请患者查房预约单&#xff0c;医生在小程序上对预约单进行接单&#xff0c;护士开始查房后填写查房小结&#xff0c;客户需要对用户信息进行授权&#xff0c;医生查房后进行签字&#xff…...

Linux_共享内存通信

目录 1、共享内存原理 2、申请共享内存 2.1 ftok 2.2 测试shmget、ftok 2.3 查看系统下的共享内存 3、关联共享内存 3.1 测试shmat 4、释放共享内存 4.1 测试shmctl 5、实现共享内存通信 6、共享内存的特性 结语 前言&#xff1a; 在Linux下&#xff0c;有一…...

自动化测试的艺术:Postman 脚本使用指南

Postman 是一个强大的 API 开发和测试工具&#xff0c;它内置了脚本功能&#xff0c;允许用户在请求发送前后执行自定义的 JavaScript 代码&#xff0c;从而实现测试流程的自动化。本文将详细介绍如何在 Postman 中使用脚本进行自动化测试&#xff0c;包括测试脚本的编写、运行…...

15万级!2.0T+2.0T双擎+8AT,大5座SUV!

最近汽车圈热度大多聚集在比亚迪汽车,比亚迪汽车新发布了两款全新中级车型,并且定价极低,不少消费者对此非常关注。其实除了比亚迪汽车有新车上市以外,还有一系列的新车也陆续上市了,只不过关注的小伙伴不多。近期广汽传祺GS8的5座豪华版正式迎来上市,厂家指导价15.98万元…...

性能强硬+配置更新五十铃纯电版D-MAX或将于2025年上市

近日,五十铃在泰国曼谷国际汽车展览会前发布了D-MAX BEV原型车。据悉,五十铃曾计划到2030年在全球推出多款电动车型,涵盖皮卡、SUV、客车等多个细分市场。本次即将登场的D-MAX BEV则是五十铃计划里的首款纯电动皮卡。根据此前公布的信息,D-MAX BEV虽然是一款纯电皮卡,但其…...

被冷落的美系中级车!迈锐宝XL跌幅达6万,可惜30天才卖311辆

这两年国内新能源的崛起,让曾经在中级车销量边缘的车型,真的是更加艰难了,其中典型的例子就有迈锐宝XL、起亚K5、现代索纳塔、别克君威等车型,如果没有新势力的崛起,或许它们还能够在市场上取得不错的销量表现,但是从现在的汽车市场局面来看,它们已经很难有一番作为了。…...

shell脚本:将一维数组以二维数组显示

shell脚本:将一维数组改成二维数组显示 1.编辑脚本文件 vi output_array.sh2.编写脚本 #!/bin/bash# 假设一维数组one_array已经包含9个元素 one_array=(1 2 3 4 5 6 7 8 9) # 获取数组长度 length=...

低代码开发难吗?

在软件开发的多样化浪潮中&#xff0c;低代码开发平台以其简化的编程模型&#xff0c;为IT行业带来了新的活力。作为一位资深的IT技术员&#xff0c;我对低代码开发平台的易用性和强大功能有着深刻的认识。今天&#xff0c;我将分享我对YDUIbuilder这一免费开源低代码平台的使用…...

分布式拒绝服务解决方式

在网络安全领域中&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击始终占据着举足轻重的地位&#xff0c;其影响力不容忽视。随着网络技术的日新月异和网络环境的日益复杂化&#xff0c;DDoS攻击不仅变得愈发频繁&#xff0c;而且其破坏性和影响力也呈现出惊人的增…...