21.<基于Spring圖書管理系統②(圖書列表+刪除圖書+更改圖書)(非強制登錄版本完結)>

PS:

開閉原則

定義和背景
開閉原則(Open-Closed Principle, OCP),也稱為開放封閉原則,是面向對象設計中的一個基本原則。該原則強調軟件中的模塊、類或函數應該對擴展開放,對修改封閉。這意味著一個軟件實體應該在不修改現有代碼的基礎上,能夠適應新的變化和需求。

核心思想
開閉原則的核心思想是:

  • 對擴展開放:當新的需求或變化出現時,可以通過擴展現有代碼來適應新的情況,而不是修改現有的代碼。
  • 對修改封閉:一旦類或模塊設計完成,就應該能夠獨立完成其工作,不再對其進行任何修改。(能夠兼容之前的版本)

針對先上線的程序而言

比如后端接口從A改成了B。(前端接口也要修改)

如果后端先上線:前端調用就會出錯,找不到A接口

如果前端先上線,前端調用依然會報錯,找不到B接口。因為此時后端還沒上線。

正確的做法:后端對之前的接口進行兼容,如果兼容則同時存在A和B接口

實現方式
實現開閉原則的方式主要包括:

  • 抽象編程:通過面向對象的繼承和多態機制,實現對抽象體的繼承和方法的覆寫,從而實現新的擴展方法。
  • 依賴抽象:類依賴于固定的抽象,而不是具體的實現,這樣可以保證類的穩定性。

相關設計原則
開閉原則與其他設計原則密切相關,包括:

  • 里氏替換原則:子類對象能夠替代父類對象出現的地方,并且保證原有邏輯行為不變。
  • 接口隔離原則:接口調用方和使用者只關心自己相關的接口,不依賴于不需要的接口。
  • 依賴反轉原則:高模塊不直接依賴低模塊,而是通過抽象來互相依賴。
  • 單一職責原則:一個類或模塊只負責完成一個職責或功能。

一、圖書列表展示功能

1.1 實現分頁功能

提到展示圖書列表,就不得不提到分頁了

分頁時,數據是如何展示的呢

第1頁:顯示1-10 條的數據

第2頁:顯示11-20 條的數據

第3頁:顯示 21-30 條的數據

以此類推…

要想實現這個功能,從數據庫中進行分頁查詢,我們要使用LIMIT 關鍵字,格式為:limit 開始索引每頁顯示的條數(開始索引從0開始)。

select * from book_info where status <> 0 limit 0,10;select * from book_info where status <> 0 limit 10,10;select * from book_info where status <> 0 limit 20,10;

我們發現只有開始索引在改變。每頁顯示的條數是固定的。

開始索引的計算公式:開始索引 = (當前頁碼 - 1) * 每頁顯示條數。

因此:

1.前端發起查詢請求時,需要向服務器端傳遞的參數。

currentPage 當前頁碼 :默認值為1

pageSize 每頁顯示條數 默認值為10

注:

為了項目更好的擴展性,通常不設置固定值,而是是以參數的形式來進行傳遞

擴展性: 軟件系統具備面對未來需求變化而進行擴展的能力。比如當前需求一頁顯示10條,后期需求改為一頁顯示20條,

后端代碼不需要任何修改。

2. 后端響應時,需要響應給前端的數據。

**records :**所查詢到的數據列表(存儲到List集合中)

count:總記錄數(用于告訴前端顯示多少頁,

顯示頁數為:(count+ pageSize -1)/pageSize

翻頁請求和響應部分, 我們通常封裝在兩個對象中

1.1.1 翻頁請求對象PageRequest

創建PageRequest

前端進行請求

1.會請求當前頁 和 每頁顯示的個數。

2.由上面兩個數據計算出offset,用作參數傳遞給SQL語句

package com.qiyangyang.springbook.demos.model;
import lombok.Data;
@Data
public class PageRequest {private Integer currentPage = 1;//當前頁private Integer pageSize = 10;//每頁顯示個數private Integer offset;/*** 從多少條記錄開始查詢* @return*/public Integer getOffset() {return (currentPage-1) * pageSize;}
}
1.1.2 翻頁響應對象
package com.qiyangyang.springbook.demos.model;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.List;/*** 定義一個泛型類,就是,這個地方不定義具體類型* 我們在進行對象的生成的時候,它才有具體的類型。* @param <T>*/
//上面兩個注解用來創建構造方法
@AllArgsConstructor
@NoArgsConstructor
@Data
public class PageResult<T> {/*** 返回的結果也是一個泛型* 不定義具體類型,在對象的創建才會有具體類型*/private List<T> records; //當前頁數據private Integer count; //所有記錄數private PageRequest pageRequest; //小駝峰,用來返回給前端當前頁數// 這里將整個對象告訴result。用來給前端獲取多少頁}

返回結果中, 使用泛型來定義記錄的類型

后端定義參數。

offset(起始序號)和limit(顯示多少條)

MySQL語句

前端根據總記錄數,來顯示分了多少頁。

1.2使用枚舉來處理status/stateCN字段。 (可借閱/不可借閱)

1.創建enums文件夾

2.創建BookStatusEnums類

package com.qiyangyang.springbook.demos.enums;/*** 枚舉類* 可以列舉出來的,是一個有限的個數,我們將他們定義成枚舉類* 方便定義類似* 根據狀態設置描述*             if(bookInfo.getStatus() == 1){*                 bookInfo.setStateCN("可借閱");*             } else if (bookInfo.getStatus() == 2) {*                 bookInfo.setStateCN("不可借閱");*             }else {*                 bookInfo.setStateCN("無效");*             }*/
public enum BookStatusEnums {DELETE(0,"無效"), //刪除NORMAL(1,"可借閱"), //有效的FORBIDDEN(2,"不可借閱"), //禁止;private int code;private String desc;BookStatusEnums(int code, String desc) {this.code = code;this.desc = desc;}/*** 我們將這個封裝成一個方法* 根據code獲取描述** @return*/public static  BookStatusEnums getDescByCode(int code){switch (code){case 0: return BookStatusEnums.DELETE;case 1: return BookStatusEnums.NORMAL;case 2: return BookStatusEnums.FORBIDDEN;}return BookStatusEnums.DELETE;}public int getCode() {return code;}public String getDesc() {return desc;}
}

稍后在業務層我們會對這個方法進行調用

1.3約定前后端交互接口

接口定義:

url:/book/getListByPagecurrentPage=1

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

參數:

當前頁數

返回結果:

當前頁的數據+總記錄數(決定前端顯示多少頁數)

我們約定,瀏覽器給服務器發送一個

/book/getListByPage 這樣的 HTTP 請求,

通過 currentPage 參數告訴服務器,當前請求為第幾頁的數據,

后端根據請求參數,返回對應頁的數據

第一頁可以不傳參數, currentPage默認值為1。

1.4實現服務器代碼

1.4.1控制層:

完善 BookController

    @RequestMapping("getListByPage")public PageResult<BookInfo> getListByPage(PageRequest pageRequest){log.info("查詢列表信息,pageRequest:{}",pageRequest);if(pageRequest.getCurrentPage()< 1){return null;}//這里返回null。會導致前端不知道是沒有數據為null。還是當前頁錯誤返回null//先不管,后續改進/*** 通過Service來去調用數據庫*/return bookService.getListByPage(pageRequest);}
1.4.2 業務層 :

完善 BookService

    public PageResult<BookInfo> getListByPage(PageRequest pageRequest) {/*** 1.查詢記錄的總數* 2.查詢當前頁的數據*/Integer count = bookInfoMapper.count();//bookInfos來接收查詢到的數據List<BookInfo> bookInfos = bookInfoMapper.queryListByPage(pageRequest);for(BookInfo bookInfo : bookInfos){/*** 根據book狀態設置描述(stateCN)*/                    bookInfo.setStateCN(BookStatusEnums.getDescByCode(bookInfo.getStatus()).getDesc());}return new PageResult<>(bookInfos,count);}
1.4.3數據層:

完善 BookInfoMapper

    /*** 查詢總數* @return*///count(1):返回滿足條件的記錄數(即行數)。count(1) 和 count(*) 基本等效,都是用于統計記錄數。@Select(("select count(1) from book_info where status <> 0"))Integer count();//希望把新添加的圖書放到下面,因此order by id desc降序。@Select("select * from book_info where status <> 0 order by id desc limit #{offset},#{pageSize}")List<BookInfo> queryListByPage(PageRequest pageRequest);

1.5校驗后端

不用傳參也行,因為我們默認currentPage 為1。且pageSize為5。

我們發現返回正確。

總記錄數也返回正確。為46。

我們發現后端接口沒有問題。

1.6實現前端代碼

1.6.1顯示圖書數據的內容

將前端標簽中的內容,也就是

        <tbody>//這里的內容我們用findHtml變量拼接并傳送到這個標簽里了</tbody>

我們寫在ajax中使用findHtml變量進行拼接。并用如下方法傳送到這個標簽中。

$("tbody").html(findHtml); //塞到tbody這個標簽里面
            success: function (result) {var books = result.records;console.log(books); //如果前端沒有報錯,那么我們打印日志。觀察后端返回結果對不對var findHtml = "";  //用這個變量來拼接HTMLfor (var book of books) {//拼接html。假如后端返回10個tr那么直接for循環拼接在這里面。findHtml//我們用單引號拼接,因為里面有雙引號findHtml += '<tr>';findHtml += '<td><input type="checkbox" name="selectBook" value="' +book.id +'" id="selectBook" class="book-select"></td>';findHtml += "<td>" + book.id + "</td>";findHtml += "<td>" + book.bookName + "</td>";findHtml += "<td>" + book.author + "</td>";findHtml += "<td>" + book.count + "</td>";findHtml += "<td>" + book.price + "</td>";findHtml += "<td>" + book.publish + "</td>";findHtml += "<td>" + book.stateCN + "</td>";findHtml += "<td>";findHtml += '<div class="op">';findHtml +='<a href="book_update.html?bookId=' + book.id + '">修改</a>';findHtml +='<a href="javascript:void(0)" onclick="deleteBook('+book.id +')">刪除</a>';findHtml += "</div>";findHtml += "</td>";findHtml += "</tr>";}$("tbody").html(findHtml); //塞到tbody這個標簽里面?
1.6.2處理翻頁信息

我們需要在前端head標簽中引入jquery 和 paginator

相當于引入插件

    <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><div class="demo"><ul id="pageContainer" class="pagination justify-content-center"></ul></div>//處理翻頁信息console.log(result);console.log(result.pageRequest);//翻頁信息$("#pageContainer").jqPaginator({totalCounts: result.count, //總記錄數pageSize: 10, //每頁的個數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;}},});

1.7校驗前后端

成功實現圖書列表顯示以及翻頁功能。

二、修改圖書列表功能

2.1約定前后端交互接口

1.進入修改頁面,需要顯示當前 Id 圖書的信息

[請求]

/book/queryBookByIdbookId=25

[參數]

bookId

[響應]

{

“id”: 25,

“bookName”: “圖書21”,

“author”: “作者2”,

“count”: 999,

“price”: 222.00,

“publish”: “出版社1”,

“status”: 2,

“statusCN”: null,

“createTime”: “2023-09-04T04:01:27.000+00:00”,

“updateTime”: “2023-09-05T03:37:03.000+00:00”

}

根據圖書ID,獲取當前圖書的信息

2.點擊修改按鈕,修改圖書信息

[請求]

/book/updateBook

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

[參數]

id=1&bookName=圖書1&author=作者1&count=23&price=36&publish=出版社1&status=1

[響應] true/false

我們約定,

瀏覽器給服務器發送一個 /book/updateBook 這樣的HTTP請求,

form表單的形式來 提交數據

服務器返回處理結果,

返回"修改成功"修改圖書成功,否則,返回失敗信息.

2.2實現服務器端代碼

2.2.1控制層:

    @RequestMapping("/queryBookById")public BookInfo queryBookById(Integer bookId){log.info("查詢圖書信息,bookId:"+bookId);if(bookId == null || bookId<=0){return new BookInfo();}return bookService.queryBookById(bookId);}@RequestMapping("/updateBook")//先使用boolean類型返回。后續我們還會再進行完善。public boolean upDateBook(BookInfo bookInfo){log.info("修改圖書信息, updateBook{}:",bookInfo);if(!StringUtils.hasLength(bookInfo.getBookName())|| !StringUtils.hasLength(bookInfo.getAuthor())|| !StringUtils.hasLength(bookInfo.getPublish())|| bookInfo.getCount() <=0|| bookInfo.getPrice()==null){return false;}try {Integer result = bookService.updateBook(bookInfo);if(result <= 0){return false;}}catch (Exception e){log.error("更新圖書失敗");return false;}return true;}

2.2.2 業務層 :

    public BookInfo queryBookById(Integer bookId) {return bookInfoMapper.queryBookById(bookId);}public Integer updateBook(BookInfo bookInfo) {return bookInfoMapper.updateBook(bookInfo);}

2.2.3數據層:

    /*** 根據Id查詢圖書信息* @param id* @return*/@Select("select * from book_info where status <> 0 and  id = #{id}")BookInfo queryBookById(Integer id);/*** 根據Id修改圖書信息*/Integer updateBook(BookInfo bookInfo);

根據 Id 修改圖書信息 我們使用的是XML方式實現的SQL

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qiyangyang.springbook.demos.mapper.BookInfoMapper"><update id="updateBook">update book_info<set><if test="bookName != null">book_name = #{bookName},</if><if test="author != null">author = #{author},</if><if test="count != null">count  = #{count},</if><if test="price != null">price = #{price},</if><if test="publish != null">publish = #{publish},</if><if test="status != null">status = #{status},</if></set>where id = #{id}</update>
</mapper>

2.3校驗后端

我發現這個接口都校驗成功。

2.3.1校驗queryBookById接口

2.3.2校驗updateBook接口

修改成功!

2.4實現前端代碼

注意:前端傳遞數據的時候記得加上id。

    <script type="text/javascript" src="js/jquery.min.js"></script><script>//查詢當前ID圖書$.ajax({type: "get",url: "book/queryBookById"+location.search,success:function(book){if(book!=null){$("#bookId").val(book.id);$("#bookName").val(book.bookName);$("#bookAuthor").val(book.author);$("#bookStock").val(book.count);$("#bookPrice").val(book.price);$("#bookPublisher").val(book.publish);$("#bookStatus").val(book.status);}}});//更新當前Id圖書function update() {$.ajax({type: "get",url: "/book/updateBook",data:$("#updateBook").serialize(),//提交整個表單success:function(result){if(result == true){alert("更新成功");location.href = "book_list.html"}else{alert("更新失敗");}}});}</script>

2.5整體測試

比如我們要將圖書ID為135的圖書

作者 修改為 洋洋

數量 修改為 888

價格 修改為 666

出版社 修改為 人民出版社

可借閱 修改為 不可借閱

修改成功!!!!!

三、邏輯刪除圖書

刪除圖書分為

邏輯刪除(update):

從邏輯上進行刪除,數據并沒有真實刪除

物理刪除(delete語句):

數據真實刪除。

但數據并沒有真實清空,只是數據庫上看不到了。

硬件存儲上還是存在的

刪除并歸檔(操作交為復雜):insert into… select…語句

1.刪除(delete or update)

2.歸檔(把已經刪除的數據存儲下來)

3.1約定前后端交互接口

邏輯刪除的話,

依然是更新邏輯,我們可以直接使用修改圖書的接口

[請求]

/book/updateBook

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

[參數]

id=1&status=0

[響應]

true / false

3.2實現服務器代碼

3.2.1控制層:

由于我們在upadate接口中只需要傳遞 id 和 status 兩個參數。

因此我們需要修改控制層中的校驗參數的步驟

    @RequestMapping("/updateBook")//先使用boolean類型返回。后續我們還會再進行完善。public boolean upDateBook(BookInfo bookInfo){log.info("修改圖書信息, updateBook{}:",bookInfo);if(!StringUtils.hasLength(bookInfo.getBookName())|| !StringUtils.hasLength(bookInfo.getAuthor())|| !StringUtils.hasLength(bookInfo.getPublish())|| bookInfo.getCount() <=0|| bookInfo.getPrice()==null){return false;}try {Integer result = bookService.updateBook(bookInfo);if(result <= 0){return false;}}catch (Exception e){log.error("更新圖書失敗");return false;}return true;}

修改為

    @RequestMapping("/updateBook")//先使用boolean類型返回。后續我們還會再進行完善。public boolean updateBook(BookInfo bookInfo){log.info("修改圖書信息, updateBook{}:",bookInfo);if(bookInfo.getId()<0){return false;}try {Integer result = bookService.updateBook(bookInfo);if(result <= 0){return false;}}catch (Exception e){log.error("更新圖書失敗");return false;}return true;}
3.2.2 業務層 :

同之前的updateBook一樣

    public Integer updateBook(BookInfo bookInfo) {return bookInfoMapper.updateBook(bookInfo);}
3.2.3數據層:

同之前的update一樣

    /*** 根據Id修改圖書信息*/Integer updateBook(BookInfo bookInfo);<update id="updateBook">update book_info<set><if test="bookName != null">book_name = #{bookName},</if><if test="author != null">author = #{author},</if><if test="count != null">count  = #{count},</if><if test="price != null">price = #{price},</if><if test="publish != null">publish = #{publish},</if><if test="status != null">status = #{status},</if></set>where id = #{id}</update>

校驗后端接口

134號圖書 status 成功修改為0

3.3實現前端代碼

        function deleteBook(id) {//刪除圖書var isDelete = confirm("確認刪除?");if (isDelete) {$.ajax({type: "post",url: "/book/updateBook",data:{id: id,status: 0},success:function(result){if(result == true){alert("刪除成功");location.href = "book_list.html";}}});}}

3.4整體校驗

刪除132號圖書三體

成功刪除!!!!!!!!!!!

四、批量邏輯刪除

4.1定義前后端交互接口

請求:

/book/batchDeleteBook

參數:

響應:

true/false

4.2實現服務器端代碼

4.2.1控制層:

注意加上:注解@RequestParam

    @RequestMapping("/batchDelete")public boolean batchDelete(@RequestParam List<Integer> ids){log.info("批量刪除數據,ids:{}",ids);try {Integer result = bookService.batchDelete(ids);if(result <= 0){return false;}}catch (Exception e){log.info("批量刪除失敗,id:{},e:{}", ids, e);return false;}return true;}
4.2.2 業務層 :
    public Integer batchDelete(List<Integer> ids) {return bookInfoMapper.batchDelete(ids);}
4.2.3數據層:

注意加上注解:

@Param(“ids”)

    Integer batchDelete(@Param("ids") List<Integer> ids);<update id="batchDelete">update book_infoset status = 0where id in<foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></update>

4.3后端校驗

后端操作成功

4.4實現前端代碼

        function batchDelete() {var isDelete = confirm("確認批量刪除?");if (isDelete) {//獲取復選框的idvar ids = [];$("input:checkbox[name='selectBook']:checked").each(function () {ids.push($(this).val());});console.log(ids);$.ajax({type: "post",url: "/book/batchDelete?ids="+ids,success:function(result){if(result == true){alert("批量刪除成功");location.href = "book_list.html";}else{alert("刪除失敗,請聯系管理員!");}}});}}

4.5整體測試

測試成功!!!!

五、強制登錄

這個功能的實現我們下一篇文章再講哦!!!!

到這里其實這個圖書管理系統的功能就基本實現完成了。

不過對于這個圖書管理系統。

我們沒有進行登錄也可以進行操作。

因此我們下一篇文章會詳細講解強制登錄功能。

并且后續會講到統一功能!!!!!!!!!!!!!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64770.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64770.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64770.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三、GIT與Github推送(上傳)和克隆(下載)

GIT與Github推送&#xff08;上傳&#xff09;和克隆&#xff08;下載&#xff09; 一、配置好SSH二、在Github創建倉庫三、git克隆&#xff08;下載&#xff09;文件四、git推送&#xff08;上傳&#xff09;文件到遠程倉庫 一、配置好SSH Git與Github上傳和下載時需要使用到…

網工日記:FTP兩種工作模式的區別

FTP 的主動模式和被動模式在連接建立的發起方、數據傳輸端口以及對網絡環境的適應性等方面存在明顯區別&#xff1a; 1. 連接發起方 主動模式&#xff1a;數據連接由服務器主動發起。在控制連接建立后&#xff0c;客戶端通過 PORT 命令告知服務器自己用于接收數據的臨時端口號…

【數字化】華為一體四面細化架構藍圖

導讀&#xff1a;華為的“一體四面”企業架構設計方法是一種綜合性的管理框架&#xff0c;它通過業務架構、信息架構、應用架構和技術架構的集成設計&#xff0c;構建出一個既符合業務需求&#xff0c;又具備高度靈活性和可擴展性的IT系統。這種架構設計方法強調從業務視角出發…

【linux板卡】lubancat通過vnc遠程訪問桌面

魯班貓開發板通過遠程VNC連接桌面&#xff1a; 硬件&#xff1a;lubancat2&#xff0c;網線 軟件&#xff1a;ssh軟件&#xff0c;vnc viewer 參考鏈接&#xff1a;https://training.eeworld.com.cn/video/38821 1、ssh連接lubancat2 &#xff0c;輸入ifconfig查看ip 2、輸入 …

解決Springboot整合Shiro+Redis退出登錄后不清除緩存

解決Springboot整合ShiroRedis退出登錄后不清除緩存 問題發現問題解決 問題發現 如果再使用緩存管理Shiro會話時&#xff0c;退出登錄后緩存的數據應該清空。 依賴文件如下&#xff1a; <dependency><groupId>org.springframework.boot</groupId><arti…

2024國城杯 Web

這四道題目Jasper大佬都做了鏡像可以直接拉取進行復現 https://jaspersec.top/2024/12/16/0x12%20%E5%9B%BD%E5%9F%8E%E6%9D%AF2024%20writeup%20with%20docker/ n0ob_un4er 這道題沒有復現成功, 不知道為啥上傳了文件, 也在 /tmp目錄下生成了sess_PHPSESSID的文件, 但是就是…

el-input輸入框需要支持多輸入,最后傳輸給后臺的字段值以逗號分割

需求&#xff1a;一個輸入框字段需要支持多次輸入&#xff0c;最后傳輸給后臺的字段值以逗號分割 解決方案&#xff1a;結合了el-tag組件的動態編輯標簽 那塊的代碼 //子組件 <template><div class"input-multiple-box" idinputMultipleBox><div>…

nginx 的 server 塊配置解析

前后端分離&#xff08;前端 flask&#xff09;&#xff1a; # 阻止ip訪問server {# default_server 是一個配置參數&#xff0c;用于指定當請求的域名&#xff08;Host 頭&#xff09;沒有匹配任何 server 塊時&#xff0c;Nginx 應該使用哪個 server 塊來處理這些請求。 lis…

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理網絡&#xff0c;因此需要在文件夾/etc/netplan下的01-network-manager-all.yaml中修改&#xff0c;需要權限&#xff0c;使用sudo vim或者其他編輯器&#xff0c;修改后的內容如下&#xff1a; # Let NetworkManager manage all devices on …

‘vue-cli-service‘ 不是內部或外部命令,也不是可運行的程序 或批處理文件。

這個錯誤信息表示系統找不到 vue-cli-service 命令&#xff0c;通常是因為 Vue 項目沒有正確安裝所需的依賴包。解決這個問題的步驟如下&#xff1a; 1. 確保你已經安裝了依賴 首先&#xff0c;確保你在項目目錄下&#xff0c;并且運行了以下命令來安裝項目所需的依賴&#x…

解決virtualbox克隆ubuntu虛擬機之后IP重復的問題

找遍了國內論壇&#xff0c;沒一個能解決該問題的&#xff0c;所以我自己寫個文章吧&#xff0c;真討厭那些只會搬運的&#xff0c;污染國內論壇環境&#xff0c;搜一個問題&#xff0c;千篇一律。 問題 操作系統版本為"Ubuntu 24.04 LTS" lennytest1:~$ cat /etc…

基于SpringBoot的寵物寄養系統的設計與實現(源碼+SQL+LW+部署講解)

文章目錄 摘 要1. 第1章 選題背景及研究意義1.1 選題背景1.2 研究意義1.3 論文結構安排 2. 第2章 相關開發技術2.1 前端技術2.2 后端技術2.3 數據庫技術 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系統需求分析 4. 第4章 系統概要設計4.1 系統功能模塊設計4.2 數據庫設計 5.…

idea 開發Gradle 項目

在Mac上安裝完Gradle后&#xff0c;可以在IntelliJ IDEA中配置并使用Gradle進行項目構建和管理。以下是詳細的配置和使用指南&#xff1a; 1. 驗證Gradle是否已安裝 在終端運行以下命令&#xff0c;確保Gradle安裝成功&#xff1a; gradle -v如果輸出Gradle版本信息&#xff…

REST與RPC的對比:從性能到擴展性的全面分析

在微服務架構中&#xff0c;服務間通信是核心問題之一。常見的兩種通信方式是REST&#xff08;Representational State Transfer&#xff09;和RPC&#xff08;Remote Procedure Call&#xff09;。它們各有優缺點&#xff0c;適用于不同場景。本文將從性能、擴展性、兼容性和開…

【Linux】:線程安全 + 死鎖問題

&#x1f4c3;個人主頁&#xff1a;island1314 &#x1f525;個人專欄&#xff1a;Linux—登神長階 ?? 歡迎關注&#xff1a;&#x1f44d;點贊 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 1. 線程安全和重入問題&…

Mysql超詳細安裝配置教程(保姆級)

目錄 一、下載Mysql 二、安裝Mysql 三、配置Mysql 四、連接Mysql 五、部分疑難問題 一、下載Mysql 從官網下載MySQL&#xff0c;這里我選用的是Mysql8.0.34版本 二、安裝Mysql 下載完成后直接雙擊進行安裝&#xff0c;打開后的頁面如下所示&#xff1a; “Developer Defa…

WFP Listbox綁定數據后,數據變化的刷新

Listbox綁定數據通過ItemsSource來的&#xff0c;如果綁定的是普通的List<數據>&#xff0c;不會自己刷新。 使用ObservableCollection集合 解決問題的方法: 將數組替換為 ObservableCollection ObservableCollection 是專為綁定設計的集合類型&#xff0c;可以通知 W…

JVM 及內存管理:掌握 Java 8 的內存模型與垃圾回收機制

Java 虛擬機&#xff08;JVM&#xff09;是運行 Java 程序的核心&#xff0c;它負責代碼執行和內存管理。Java 8 引入了一些重要的內存模型和垃圾回收機制優化。本文將詳細解析 JVM 的內存模型、垃圾回收機制&#xff0c;并配以相關圖解&#xff0c;幫助你深刻理解 JVM 的工作原…

Maple軟件的安裝和使用

文章目錄 1.前言說明2.我為什么要學習Maple3.軟件的安裝4.如何使用4.1基本的賦值語句4.2函數的定義4.3三個類型的書寫介質 5.指數運算5.1使用面板5.2自己輸入 6.對數的使用 1.前言說明 眾所周知&#xff0c;我雖然是一名這個計算機專業的學生&#xff0c;但是我對于數學&#…

【超級詳細】Vue3項目上傳文件到七牛云的詳細筆記

概述 繼上一篇筆記介紹如何綁定七牛云的域名之后&#xff0c;這篇筆記主要介紹了如何在Vue3項目中實現文件上傳至七牛云的功能。我們將使用Cropper.js來處理圖像裁剪&#xff0c;并通過自定義組件和API調用來完成整個流程。 這里直接給出關鍵部分js代碼&#xff0c;上傳之前要先…